{"record":{"id":"83f5c5fb3333c703","repo":"nexu-io/open-design","slug":"authorized-pull-receipt-has-invalid-key","errorCode":null,"errorMessage":"authorized pull receipt has invalid ${key}","messagePattern":"authorized pull receipt has invalid (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/daemon/src/collab/authorized-team-project-pull.ts","lineNumber":97,"sourceCode":"\ninterface ReceiptValidationInput {\n  projectId: string;\n  scope: TeamMirrorPullScope;\n  expectedVersion: number;\n  nowMs?: number;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n  return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction requiredString(\n  record: Record<string, unknown>,\n  key: string,\n): string {\n  const value = record[key];\n  if (typeof value !== 'string' || !value.trim()) {\n    throw new Error(`authorized pull receipt has invalid ${key}`);\n  }\n  return value;\n}\n\nfunction parseReceipt(stdout: string): AuthorizedTeamProjectPullReceipt {\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(stdout.trim());\n  } catch {\n    throw new Error('authorized pull response is not valid JSON');\n  }\n  if (!isRecord(parsed)) {\n    throw new Error('authorized pull response must be an object');\n  }\n  const version = parsed.version;\n  if (!Number.isSafeInteger(version) || Number(version) < 0) {\n    throw new Error('authorized pull receipt has invalid version');\n  }","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/collab/authorized-team-project-pull.ts#L79-L115","documentation":"Thrown by requiredString while parseReceipt validates the JSON returned by the Vela `team-projects pull` authorizer. Each receipt field (workspaceId, resourceTeamId, viewerMemberId, ownerMemberId, projectId, resourceId, versionId, manifestDigest, authorizedAt, expiresAt) must be a non-empty string; the `${key}` names which field failed. This is a contract check between Open Design and the Vela CLI/server that produced the receipt.","triggerScenarios":"The Vela CLI returned valid JSON but one receipt field was missing, null, an empty string, or a non-string type (e.g. a number where a string id was expected).","commonSituations":"Version skew between the daemon's expected receipt schema and the Vela CLI/server version that produced it, a partial/truncated stdout capture, or a server-side change that renamed a field.","solutions":["Check the error message for which `${key}` is invalid and inspect the raw Vela stdout.","Ensure the Vela CLI / server version matches what this daemon build expects (upgrade or pin accordingly).","Re-run the authorized pull; transient partial output can produce this.","If you control the server, confirm the receipt emits all required string fields non-empty."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function hasAllReceiptStrings(parsed: unknown, keys: string[]): boolean {\n  if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return false;\n  const rec = parsed as Record<string, unknown>;\n  return keys.every((k) => typeof rec[k] === 'string' && (rec[k] as string).trim().length > 0);\n}\nconst REQUIRED = ['workspaceId','resourceTeamId','viewerMemberId','ownerMemberId','projectId','resourceId','versionId','manifestDigest','authorizedAt','expiresAt'];","typeGuard":null,"tryCatchPattern":"try {\n  parseReceipt(stdout);\n} catch (err) {\n  if (err instanceof Error && /receipt has invalid/.test(err.message)) {\n    // log raw stdout, signal a version-skew issue, do not proceed with the pull\n  }\n  throw err;\n}","preventionTips":["Keep the daemon and Vela CLI/server versions in lockstep so the receipt schema matches.","Log the raw stdout on any receipt error for post-mortem.","Unit-test parseReceipt against fixture receipts that match the current contract."],"tags":["collab","vela","receipt","validation","team-projects"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}