can1357/oh-my-pi · error · Error
plik upload metadata did not include an id and upload token
Error message
plik upload metadata did not include an id and upload token
What it means
Thrown by the plikUpload validator when the Plik upload server's JSON response is missing either the 'id' or 'uploadToken' field (or is not an object). Both are required to finalize a Plik upload: id identifies the upload session and uploadToken authorizes subsequent calls.
Source
Thrown at packages/coding-agent/src/blob-broker/uploaders-self-hosted.ts:73
throw new Error("owncloud share response did not include OCS metadata and data");
}
const meta = ocs.meta;
const data = ocs.data;
if (typeof meta !== "object" || meta === null || !("statuscode" in meta)) {
throw new Error("owncloud share response did not include an OCS status");
}
if (typeof data !== "object" || data === null || !("url" in data)) {
throw new Error("owncloud share response did not include a URL");
}
const url = nonEmptyString(data.url);
if (!url) throw new Error("owncloud share response did not include a URL");
const id = "id" in data ? identifier(data.id) : undefined;
return { statusCode: meta.statuscode, url, ...(id ? { id } : {}) };
}
function plikUpload(value: unknown): PlikUpload {
if (typeof value !== "object" || value === null || !("id" in value) || !("uploadToken" in value)) {
throw new Error("plik upload metadata did not include an id and upload token");
}
const id = identifier(value.id);
const uploadToken = nonEmptyString(value.uploadToken);
if (!id || !uploadToken) throw new Error("plik upload metadata did not include an id and upload token");
let downloadBase: string | undefined;
if ("downloadURL" in value) downloadBase = nonEmptyString(value.downloadURL);
if (!downloadBase && "downloadDomain" in value) downloadBase = nonEmptyString(value.downloadDomain);
return { id, uploadToken, ...(downloadBase ? { downloadBase } : {}) };
}
function requiredStringOption(config: DestinationRuntimeConfig, key: string): string {
const value = requireOption(config, key);
if (typeof value !== "string" || value.trim() === "") {
throw new Error(`Destination option ${key} must be a non-empty string`);
}
return value.trim();
}
View on GitHub (pinned to 9690622007)
Solutions
- Check that the configured plik apiUrl points to the Plik API root (e.g. https://plik.example.com) not a UI route
- Verify the server's response with curl (curl -F file=@x https://plik.example.com) — it should contain id and uploadToken
- Check Plik server logs for rejection reasons (size limits, auth requirements, expired tokens)
- Ensure any required Plik authentication options are set in the destination config
Example fix
// before: hitting the UI path returns HTML/JSON without tokens
apiUrl = "https://plik.example.com/" // if behind a path-mangling proxy this can route wrong
// after: verify the API answers directly
const resp = await fetch("https://plik.example"); const meta = await resp.json(); if (!meta.id || !meta.uploadToken) throw new Error(meta.message ?? "plik rejected upload"); Defensive patterns
Strategy: validation
Validate before calling
const res = await fetch(plikApi, { method: "POST", body: form });
const meta = await res.json();
if (typeof meta?.id === "undefined" || typeof meta?.uploadToken !== "string" || !meta.uploadToken) {
throw new Error(`plik rejected upload: ${JSON.stringify(meta).slice(0, 200)}`);
} Type guard
function isPlikUploadMeta(value: unknown): value is { id: string | number; uploadToken: string } {
if (typeof value !== "object" || value === null) return false;
const v = value as { id?: unknown; uploadToken?: unknown };
const idOk = typeof v.id === "string" || typeof v.id === "number";
return idOk && typeof v.uploadToken === "string" && v.uploadToken.length > 0;
} Try / catch
try {
const up = await uploader.upload(blob);
} catch (err) {
if ((err as Error).message.includes("id and upload token")) {
throw new Error("plik server response lacked id/uploadToken — check apiUrl points to the Plik API and auth options are set");
}
throw err;
} Prevention
- Verify the Plik server responds correctly with curl before wiring the destination
- Point apiUrl at the plikd API root, not a UI or proxy route
- Check plikd logs for size/auth rejections that produce error payloads without tokens
When it happens
Trigger: POSTing the file to a Plik server (createPlikUploader -> metadata -> plikUpload) and receiving a JSON body without id/uploadToken — e.g. the server returned an error JSON like { message: "invalid upload" } with 200, or the endpoint URL is wrong so a different route answered.
Common situations: Misconfigured plikd URL (hitting the UI instead of the API), Plik server rejecting the request due to missing/invalid upload token header while still returning JSON, or a proxy returning a JSON error page.
Related errors
- flickr response did not include a photo ID
- the upload response did not contain a valid direct URL
- the upload response URL must use HTTP or HTTPS
- the upload endpoint returned invalid JSON
- the upload endpoint returned an invalid JSON object
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/301924ea4205e564.
Report an issue: GitHub.