{"record":{"id":"cc42742e5b166beb","repo":"windmill-labs/windmill","slug":"34000","errorCode":"34000","errorMessage":"portal ${formatProtocolName(describe.name, \"portal\")} does not exist","messagePattern":"portal (.+?) does not exist","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/src/commands/datatable/serve.ts","lineNumber":506,"sourceCode":"      isQueryLikelySafeToDescribe(statement.query)\n    ) {\n      const envelope = await executeQuery(statement.query);\n      return concat([\n        buildParameterDescription(statement.parameterTypeOids),\n        envelope.columns.length > 0\n          ? buildRowDescription(envelope.columns)\n          : buildNoData(),\n      ]);\n    }\n    return concat([\n      buildParameterDescription(statement.parameterTypeOids),\n      buildNoData(),\n    ]);\n  }\n\n  const portal = portals.get(describe.name);\n  if (!portal) {\n    throw createPgProtocolError(\n      `portal ${formatProtocolName(describe.name, \"portal\")} does not exist`,\n      \"34000\",\n    );\n  }\n\n  if (!portal.envelope && isQueryLikelySafeToDescribe(portal.query)) {\n    portal.envelope = await executeQuery(buildPortalQuery(portal));\n  }\n  if (portal.envelope?.columns.length) {\n    portal.sentRowDescription = true;\n    return buildRowDescription(portal.envelope.columns);\n  }\n  return buildNoData();\n}\n\nasync function handleExecuteMessage(\n  data: Uint8Array,\n  portals: Map<string, PortalState>,","sourceCodeStart":488,"sourceCodeEnd":524,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/commands/datatable/serve.ts#L488-L524","documentation":"PostgreSQL 'invalid_cursor_name' (34000) error: a Describe message targeting type 'P' (portal) referenced a portal name not present in the portals map. Portals are created by Bind and live only on the current connection, so describing an unknown portal is a protocol-level error.","triggerScenarios":"Client sends Describe(P, name) before any Bind created that portal, after the portal completed (portal state is cleared/rowOffset reset on completion), or after a connection reset cleared the portals map.","commonSituations":"Driver-side connection failover between Bind and Describe; cursor-style streaming clients that expect portals to persist across transactions; a failed earlier Bind (e.g. binary-format rejection from errors 1280/1281) meant the portal was never created.","solutions":["Ensure a Bind for the portal name is executed (and succeeded) before Describe(P). Check logs for a prior Bind error.","Keep the Parse→Bind→Describe→Execute sequence on one connection without reconnects; disable pooling or statement reuse that spans connections.","If streaming with cursors, re-open the portal (re-Bind) once results are exhausted instead of describing a completed portal."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await describePortal(portalName);\n} catch (e) {\n  if (e.code === '34000' || /portal .* does not exist/.test(e.message)) {\n    // re-run Bind to recreate the portal, then retry Describe\n  } else throw e;\n}","preventionTips":["Bind before every Describe(P)/Execute; treat portals as single-use.","Keep the whole Parse→Bind→Describe→Execute sequence on one connection.","Investigate any earlier Bind failure (e.g. binary format) that prevented portal creation."],"tags":["postgresql","portal","wire-protocol","cli"],"backgroundTag":"invalid-cursor-name","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}