AlistGo/alist · error
decode darkibox result failed: %w
Error message
decode darkibox result failed: %w
What it means
The API call fully succeeded (HTTP 200, provider status 200, non-empty Result) but json.Unmarshal of resp.Result into the caller's target struct failed. The response JSON shape does not match the Go struct being decoded into — schema drift or an unexpected payload type.
Source
Thrown at drivers/darkibox/util.go:48
r, err := base.RestyClient.R().
SetContext(ctx).
SetQueryParams(query).
SetResult(&resp).
Get(apiBase + endpoint)
if err != nil {
return err
}
if r.StatusCode() != http.StatusOK {
return fmt.Errorf("darkibox http error: %d", r.StatusCode())
}
if resp.Status != 200 {
return fmt.Errorf("darkibox api error: status=%d msg=%s", resp.Status, resp.Msg)
}
if out == nil || len(resp.Result) == 0 || string(resp.Result) == "null" {
return nil
}
if err := json.Unmarshal(resp.Result, out); err != nil {
return fmt.Errorf("decode darkibox result failed: %w", err)
}
return nil
}
// fldIDStr converts a folder ID (which may be the root "0") to a string suitable for API params.
func fldIDStr(id string) string {
if id == "" {
return "0"
}
return id
}
// encodeFolderID prefixes a folder ID so we can distinguish folders from files.
func encodeFolderID(id int64) string {
return "d:" + strconv.FormatInt(id, 10)
}
// encodeFileID prefixes a file code so we can distinguish files from folders.View on GitHub (pinned to 843d9dc814)
Solutions
- Log resp.Result (raw JSON) at debug level and compare it against the target struct's json tags; correct the struct
- If the provider legitimately varies the shape (object vs array), unmarshal into json.RawMessage first and branch on the first non-space byte
- Pin the driver to a known-good provider API version if the platform offers versioned endpoints
Example fix
// before
if err := json.Unmarshal(resp.Result, out); err != nil {
return fmt.Errorf("decode darkibox result failed: %w", err)
}
// after — include endpoint and a body snippet
if err := json.Unmarshal(resp.Result, out); err != nil {
return fmt.Errorf("decode darkibox result failed for %s: %w (body: %.200s)", endpoint, err, resp.Result)
} Defensive patterns
Strategy: type-guard
Validate before calling
var probe json.RawMessage
if err := d.callAPI(ctx, endpoint, params, &probe); err == nil {
if !json.Valid(probe) { return errors.New("provider returned invalid JSON") }
} Type guard
func isDecodeError(err error) bool {
return err != nil && strings.Contains(err.Error(), "decode darkibox result failed")
} Try / catch
if isDecodeError(err) {
// schema drift: log raw body, fail fast — retrying identical decode will not help
log.Errorf("schema mismatch: %v", err)
return err
} Prevention
- Log raw Result at debug level for postmortems
- Pin provider API versions when available
- Add contract tests for each endpoint's result struct
When it happens
Trigger: Result is an object where an array was expected (or vice versa) for that endpoint; numeric fields returned as strings; null inside a non-pointer field; provider added/renamed nested fields so types no longer line up with e.g. folderCreateResult or uploadServerResult.
Common situations: After a provider API update changes response casing or nesting; endpoints reused with the wrong result struct; new endpoints whose schema was guessed during driver development.
Related errors
- Too many parts, please increase part size
- no upload server URL returned
- darkibox http error: %d
- darkibox api error: status=%d msg=%s
- invalid json
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/fc413d60bfad5889.
Report an issue: GitHub.