{"record":{"id":"511bff27abc077e3","repo":"paperclipai/paperclip","slug":"ctx-db-execute-cannot-reference-public-or-other-no","errorCode":null,"errorMessage":"ctx.db.execute cannot reference public or other non-plugin schemas","messagePattern":"ctx\\.db\\.execute cannot reference public or other non-plugin schemas","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/src/services/plugin-database.ts","lineNumber":298,"sourceCode":"  }\n  const statement = statements[0]!;\n  assertNoBannedSql(statement);\n  const normalized = normaliseSql(statement);\n  if (!/^(insert\\s+into|update|delete\\s+from)\\b/.test(normalized)) {\n    throw new Error(\"ctx.db.execute only allows INSERT, UPDATE, or DELETE\");\n  }\n  if (/\\b(alter|create|drop|truncate)\\b/.test(normalized)) {\n    throw new Error(\"ctx.db.execute cannot contain DDL keywords\");\n  }\n\n  const refs = extractQualifiedRefs(statement);\n  const target = refs.find((ref) => [\"into\", \"update\", \"from\"].includes(ref.keyword));\n  if (!target || target.schema !== namespace) {\n    throw new Error(`ctx.db.execute target must be inside plugin namespace \"${namespace}\"`);\n  }\n  for (const ref of refs) {\n    if (ref.schema !== namespace) {\n      throw new Error(\"ctx.db.execute cannot reference public or other non-plugin schemas\");\n    }\n  }\n}\n\nfunction bindSql(statement: string, params: readonly unknown[] = []): SQL {\n  // Safe only after callers run the plugin SQL validators above.\n  if (params.length === 0) return sql.raw(statement);\n  const chunks: SQL[] = [];\n  let cursor = 0;\n  const placeholderPattern = /\\$(\\d+)/g;\n  const seen = new Set<number>();\n\n  for (const match of statement.matchAll(placeholderPattern)) {\n    const index = Number(match[1]);\n    if (!Number.isInteger(index) || index < 1 || index > params.length) {\n      throw new Error(`SQL placeholder $${match[1]} has no matching parameter`);\n    }\n    chunks.push(sql.raw(statement.slice(cursor, match.index)));","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/paperclipai/paperclip/blob/120ae5428fa29bee300bcf806491cd4d965fbb7c/server/src/services/plugin-database.ts#L280-L316","documentation":"Write-target guard in validatePluginRuntimeExecute: extractQualifiedRefs found no into/update/from reference, or its target schema is not the plugin namespace. Ensures every execute statement's affected object lives inside the plugin schema; the misdirected statement is at fault.","triggerScenarios":"Thrown at server/src/services/plugin-database.ts:298 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Remove references to public or other non-plugin schemas from the ctx.db.execute SQL."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"120ae5428fa29bee300bcf806491cd4d965fbb7c","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}