jackwener/OpenCLI · error · CommandExecutionError
no signed url returned for attachment ${id}
Error message
no signed url returned for attachment ${id} What it means
This CommandExecutionError is thrown after the in-page fetch for GET /attachments/:id/url completes successfully but the returned payload contains no `url` field. It indicates the server responded without the signed URL the CLI contract expects — either contract drift, an unexpected response shape, or a deleted/expired attachment.
Source
Thrown at clis/slock/attachment-url.js:45
{ name: 'attachmentId', positional: true, required: true, help: 'Attachment UUID' },
{ name: 'server', help: 'Override active server slug' },
],
columns: ['attachmentId', 'url', 'expiresAt'],
func: async (page, kwargs) => {
const id = String(kwargs.attachmentId ?? '').trim();
if (!UUID_RE.test(id)) throw new ArgumentError(`attachmentId "${id}" is not a UUID`);
await page.goto(SLOCK_HOME_URL);
const snippet = buildFetchSnippet({
method: 'GET',
path: `/attachments/${encodeURIComponent(id)}/url`,
serverScoped: true,
serverIdOverride: kwargs.server,
});
const result = await page.evaluate(`(async () => { ${snippet} })()`);
const rows = dispatchEvaluateResult(result);
const data = Array.isArray(rows) ? rows[0] : rows;
if (!data?.url) {
throw new CommandExecutionError(`no signed url returned for attachment ${id}`);
}
return [{
attachmentId: id,
url: data?.url ?? null,
expiresAt: data?.expiresAt ?? null,
}];
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Re-list attachments to confirm the attachmentId still exists and is accessible.
- Check the Slock server API version; if `/attachments/:id/url` changed shape, update the CLI.
- Retry after re-authenticating — verify the session with auth-verify in case permissions silently degraded.
- If it persists, inspect the raw response (the error implies contract drift) and report/patch dispatchEvaluateResult mapping.
Defensive patterns
Strategy: try-catch
Type guard
const hasSignedUrl = (data) => data != null && typeof data === 'object' && typeof data.url === 'string' && data.url.length > 0;
Try / catch
try {
const [row] = await attachmentUrl(page, id);
} catch (e) {
if (e instanceof CommandExecutionError && e.message.includes('no signed url returned')) {
console.error(`Attachment ${id} has no signed URL — verify it still exists`);
} else throw e;
} Prevention
- Confirm the attachment exists via listing before requesting its URL.
- Re-verify the session when signed URLs come back empty.
- Treat missing url as 'attachment unavailable', not a transient failure.
When it happens
Trigger: The dispatchEvaluateResult call returns an object whose `data.url` is undefined/null: server returns an empty object, a row missing `url`, or a null envelope for a nonexistent attachment.
Common situations: Requesting a URL for an attachment that was deleted or whose record lacks a stored file, an API version change renaming the `url` field, or the session lacking permission to mint signed URLs (server returns 200 with empty body).
Related errors
- Bilibili creator comparison API returned a malformed envelop
- Flomo API returned a malformed memo entry
- Pinterest request returned malformed API payload
- unexpected /auth/me result: ${JSON.stringify(r)}
- expected array of rows from server, got ${typeof rows} (cont
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/17c5df5f4138059a.
Report an issue: GitHub.