Skip to content

Three deserialization and request bugs in TablesDB and Storage services #10

@ChiragAgg5k

Description

@ChiragAgg5k

Bug Report

While building appwrite-rust-playground, I hit three bugs in the SDK (v0.1.0) that required raw client.call() workarounds. All three are mismatches between what the SDK sends/expects and what the API actually returns/accepts.


Bug 1: ColumnList.columns (and AttributeList.attributes) typed as Vec<String> but API returns objects

File: src/models/column_list.rs

What happens:
Calling TablesDB::list_columns() fails with:

Serialization error: invalid type: map, expected a string at line 1 column 22

Root cause:
The model defines:

pub columns: Vec<String>,

But the API returns full column objects (maps with key, type, status, error, required, array, min, max, default, etc.), not plain strings.

Suggested fix:
Change the field type to Vec<serde_json::Value>, or introduce a Column enum that can deserialize any column variant (ColumnString, ColumnInteger, ColumnBoolean, etc.) via a tagged union on the "type" field.

Note: The same bug exists in src/models/attribute_list.rs where attributes: Vec<String> should also be Vec<serde_json::Value> (or a similar typed enum).


Bug 2: create_index serializes orders as a single string instead of an array

File: src/services/tables_db.rs (also src/services/databases.rs)

What happens:
Calling TablesDB::create_index() with orders: Some(OrderBy::Asc) fails with:

Invalid `orders` param: Value must a valid array no longer than 100 items and Value must be one of (asc, desc)

Root cause:
The parameter is typed as Option<crate::enums::OrderBy> (a single enum value) and serialized with json!(value), which produces "asc". The API expects an array of order strings: ["asc"].

Suggested fix:
Change the parameter type from:

orders: Option<crate::enums::OrderBy>,

to:

orders: Option<Vec<crate::enums::OrderBy>>,

so that json!(value) produces ["asc"] matching the API spec. This applies to both services/tables_db.rs and services/databases.rs.


Bug 3: Storage::create_file hits wrong route due to upload_id appended to URL

Files: src/services/storage.rs, src/client.rs

What happens:
Calling Storage::create_file() fails with:

Route not found. Please ensure the endpoint is configured correctly and that the API route is valid for this SDK version.

Root cause:
In Storage::create_file (storage.rs), the file ID is passed as the upload_id:

self.client.file_upload(&path, ..., Some(file_id_str)).await

In Client::file_upload_with_progress (client.rs ~line 621), when upload_id is Some, the URL is constructed as:

format!("{}{}/{}", state.config.endpoint, path, id)

This makes the request POST to /storage/buckets/{bucketId}/files/{fileId}, which is not a valid create route. The create endpoint is POST /storage/buckets/{bucketId}/files (without the ID suffix). The fileId is already included in the multipart form params.

Suggested fix:
In Storage::create_file, pass None instead of Some(file_id_str) for the upload_id parameter. The upload_id / URL-append logic is only needed for resumable chunked uploads, not the initial create request:

self.client.file_upload(&path, Some(api_headers), params, "file", file, None).await

Environment

  • SDK version: 0.1.0
  • Appwrite instance: Appwrite Cloud (Frankfurt region)
  • Rust edition: 2024
  • OS: macOS

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions