Hmbown/CodeWhale · error
invalid draft id
Error message
invalid draft id
What it means
draftKey builds a KV key of the form `draft:<type>:<id>` but first validates the id against DRAFT_ID_PATTERN (/^[A-Za-z0-9._-]{1,128}$/). An id containing colons, slashes, whitespace, unicode, or longer than 128 chars throws "invalid draft id". This prevents malformed or injection-prone ids from entering the KV namespace and keeps parseDraftKey round-tripping.
Solutions
- Sanitize or slugify the id to [A-Za-z0-9._-] before calling draftKey.
- If the caller holds a full key, use parseDraftKey to extract the id instead of passing the key string as an id.
- Trim and cap input length to 128 characters at the API boundary.
- Return a 400 with a clear field error when user-supplied ids fail the pattern instead of letting it throw.
Example fix
// before draftKey(type, rawUserId); // after const id = rawUserId.trim().replace(/[^A-Za-z0-9._-]/g, '_').slice(0, 128); draftKey(type, id);
Defensive patterns
Strategy: validation
Validate before calling
const DRAFT_ID_OK = /^[A-Za-z0-9._-]{1,128}$/;
if (!DRAFT_ID_OK.test(id)) return badRequest('draft id must match [A-Za-z0-9._-]{1,128}'); Type guard
const isValidDraftId = (id) => typeof id === 'string' && /^[A-Za-z0-9._-]{1,128}$/.test(id); Prevention
- Slugify or hash user-derived ids before constructing draft keys.
- Never pass a full KV key where an id is expected — use parseDraftKey.
- Trim input at the API boundary and reject with 400 on pattern mismatch.
- Cap id length to 128 in the input schema (e.g. zod: z.string().max(128).regex(...)).
When it happens
Trigger: Calling draftKey(type, id) with an id containing ':' or '/' (e.g. a URL path or a UUID with braces), an empty string, whitespace, or a string longer than 128 characters.
Common situations: Passing a full key like 'draft:plan:abc' back in as the id; ids derived from user input (names, emails) with illegal characters; untrimmed input carrying newlines; accepting ids from untrusted POST bodies.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- invalid draft key
- Automation name is required
- Automation prompt is required
- coordinates must be finite numbers
- coordinates must be finite numbers
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/06fe1d94a066e94c.
Report an issue: GitHub.
Appendix: source
Thrown at web/lib/community-agent.ts:65
export interface UsageLog {
date: string;
calls: number;
inputTokens: number;
outputTokens: number;
}
export interface DeepSeekEnv {
baseUrl?: string;
model?: string;
}
const AGENT_DRAFT_TYPE_SET = new Set<string>(AGENT_DRAFT_TYPES);
const DRAFT_ID_PATTERN = /^[A-Za-z0-9._-]{1,128}$/;
export function draftKey(type: AgentDraftType, id: string): string {
if (!DRAFT_ID_PATTERN.test(id)) {
throw new Error("invalid draft id");
}
return `draft:${type}:${id}`;
}
export function parseDraftKey(key: string): { type: AgentDraftType; id: string } | null {
const match = /^draft:([^:]+):([^:]+)$/.exec(key);
if (!match || !AGENT_DRAFT_TYPE_SET.has(match[1]) || !DRAFT_ID_PATTERN.test(match[2])) {
return null;
}
return { type: match[1] as AgentDraftType, id: match[2] };
}
export function isAgentDraft(value: unknown): value is AgentDraft {
if (!value || typeof value !== "object") return false;
const draft = value as Record<string, unknown>;
return (
typeof draft.id === "string" &&
DRAFT_ID_PATTERN.test(draft.id) &&View on GitHub (pinned to 433685b202)