Skip to content

pi bridge (cbmem.ts) generated for legacy extension API - all tools crash on invocation with pi 0.84.x #1867

Description

@Lowpower

Environment

  • codebase-memory-mcp: 0.10.8 (macOS arm64 binary from GitHub releases; latest release at time of writing)
  • Host agent: pi (@earendil-works/pi-coding-agent) 0.84.3
  • OS: macOS 26.3 (arm64)
  • Generated file: ~/.pi/agent/extensions/cbmem.ts (via codebase-memory-mcp install)

Summary

The pi bridge extension generated by codebase-memory-mcp install registers tools with a legacy shape (run: callback, no parameters schema). Current pi (0.84.3) is incompatible with that shape in two independent ways, so every one of the 15 graph tools fails on every invocation:

  1. pi-ai's argument validation crashes with TypeError: Cannot read properties of undefined (reading 'properties')
  2. Even if validation passed, the tool body would never run

Re-running the installer (same latest version 0.10.8) regenerates a byte-identical file, so this is not local drift — the generator itself still emits the legacy API.

Root cause

1. Crash in pi-ai argument validation

Generated registration (all 15 tools):

pi.registerTool({
  name: 'index_repository',
  run: (args, ctx) => call('index_repository', args, ctx?.signal),
});

Two problems against pi 0.84.3:

  • pi's wrapToolDefinition() (dist/core/tools/tool-definition-wrapper.js) only calls definition.execute(toolCallId, params, signal, onUpdate, ctx)a run property is never invoked.
  • pi-ai's validateToolArguments() (pi-ai/dist/utils/validation.js) calls normalizeOptionalNulls(args, tool.parameters), which reads schema.properties without guarding schema itself:
// validation.js:219
if (typeof value !== "object" || value === null || !schema.properties)
//                                                ^^^^^^ tool.parameters is undefined here

With no parameters schema, tool.parameters is undefined, and any object-shaped arguments reach that line → the exact error seen in-session:

TypeError: Cannot read properties of undefined (reading 'properties')

2. Current pi API (docs/extensions.md)

Per the official extension docs, tools must be registered with a TypeBox parameters and an execute(toolCallId, params, signal, onUpdate, ctx):

import { Type } from "typebox";

pi.registerTool({
  name: "greet",
  parameters: Type.Object({ name: Type.String() }),
  async execute(toolCallId, params, signal, onUpdate, ctx) { ... },
});

Minimal repro

Fresh install of codebase-memory-mcp 0.10.8 into pi 0.84.3, then in an interactive session invoke any generated tool (e.g. list_projects). Observe the TypeError above instead of tool output.

Fix that works (verified)

Rewriting the generated block to the current API makes all 15 tools work end-to-end:

import { Type } from 'typebox';

const ANY_ARGS = Type.Object({}, { additionalProperties: true });

pi.registerTool({
  name,
  description,
  parameters: ANY_ARGS,
  async execute(_toolCallId, params, signal, _onUpdate, _ctx) {
    const result = await call(name, params ?? {}, signal);
    return toToolResult(result); // normalize to { content: [{ type: 'text', text }] }
  },
});

Details that mattered:

  • Keep the args JSON piped via stdin (cli <tool> accepts JSON on stdin) — arg-JSON deprecation warning is avoided and large payloads won't hit OS argv limits.
  • toToolResult must wrap the raw JSON into an AgentToolResult shape (content: [{ type: 'text', text }]).
  • An empty-object schema with additionalProperties: true survives pi-ai's validation and its strict-schema path.

Secondary finding: non-TTY CLI output defaults to tree for some tools

When scripting against the local CLI (as any bridge must), search_graph, trace_path, and detect_changes emit human-readable tree output by default instead of JSON, which breaks JSON parsing. They honor an explicit --format json. The other tools emit JSON by default. It would help bridge maintainers if JSON were the default on non-TTY stdout, or if this were documented where the cli <tool> '<json>' interface is described.

Suggested resolution

  • Emit the current pi API (parameters + execute) from the generator.
  • Optionally add a smoke check at install time: spawn the target agent ≥ required version, or embed a version probe, so future API drift fails loudly instead of silently.

Workaround (until fixed)

Take ownership of the generated file as its header permits: remove the codebase-memory-mcp:start/end markers and patch by hand. Downside: it will no longer be auto-regenerated on cbm install/update, so upsteam changes need manual re-porting.

Metadata

Metadata

Assignees

No one assigned

    Labels

    editor/integrationEditor compatibility and CLI integrationparsing/qualityGraph extraction bugs, false positives, missing edgesstability/performanceServer crashes, OOM, hangs, high CPU/memory

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions