Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion devframe/docs/.vitepress/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default function devframeSidebar(prefix = ''): DefaultTheme.SidebarItem[]
text: 'Error Reference',
link: `${prefix}/errors/`,
collapsed: true,
items: Array.from({ length: 18 }, (_, i) => {
items: Array.from({ length: 28 }, (_, i) => {
const code = `DF${String(i + 1).padStart(4, '0')}`
return { text: code, link: `${prefix}/errors/${code}` }
}),
Expand Down
54 changes: 54 additions & 0 deletions devframe/docs/errors/DF0019.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
outline: deep
---

# DF0019: Agent Requires JSON-Serializable RPC

> Package: `devframe`

## Message

> RPC function "`{name}`" has `agent` set but `jsonSerializable` is not `true` — MCP requires JSON-serializable data.

## Cause

The `agent` field exposes an RPC function as an MCP tool. MCP and the underlying schema-conversion path (`@valibot/to-json-schema`) only consume JSON-shaped data. Functions whose payloads can include `Map`, `Set`, `Date`, `BigInt`, circular references, or class instances cannot be safely advertised to agents.

A registered function is rejected when `agent` is present and `jsonSerializable` is not explicitly `true`.

## Example

```ts
defineRpcFunction({
name: 'my-plugin:summary',
agent: { description: 'Returns a summary' },
// missing `jsonSerializable: true` → registration throws DF0019
handler: () => ({ items: [1, 2, 3] }),
})
```

## Fix

Either declare the payload as JSON-safe:

```ts
defineRpcFunction({
name: 'my-plugin:summary',
jsonSerializable: true,
agent: { description: 'Returns a summary' },
handler: () => ({ items: [1, 2, 3] }),
})
```

Or remove `agent` to keep the function as an internal RPC (no agent exposure):

```ts
defineRpcFunction({
name: 'my-plugin:summary',
handler: () => new Map([['a', 1]]),
})
```

## Source

`packages/devframe/src/rpc/collector.ts`
58 changes: 58 additions & 0 deletions devframe/docs/errors/DF0020.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
outline: deep
---

# DF0020: Non-JSON Value in JSON-Serializable RPC

> Package: `devframe`

## Message

> RPC function "`{name}`" declares `jsonSerializable: true` but the value at "`{path}`" is a `{type}`.

## Cause

The function is declared `jsonSerializable: true`, which means its args and return value are encoded with strict `JSON.stringify` (both on the wire and in build dumps). The strict serializer rejects any value that JSON cannot round-trip losslessly:

- `Map`, `Set`, `WeakMap`, `WeakSet`
- `Date` (silently coerced to ISO string by JSON)
- `BigInt`
- circular references
- non-plain class instances
- `undefined` leaves
- `Symbol`
- `Function`

When the strict serializer encounters one of these, it throws synchronously at the offending call rather than producing a corrupt payload.

## Example

```ts
defineRpcFunction({
name: 'my-plugin:graph',
jsonSerializable: true,
handler: () => ({
nodes: new Map([['a', 1]]), // ← throws DF0020 with type=Map, path="nodes"
}),
})
```

## Fix

Either drop `jsonSerializable: true` so the function uses `structured-clone-es` (round-trips `Map`, `Set`, etc.):

```ts
defineRpcFunction({
name: 'my-plugin:graph',
// jsonSerializable: false (default) — Map/Set survive the wire and the dump
handler: () => ({
nodes: new Map([['a', 1]]),
}),
})
```

Or convert the payload to a JSON-safe shape (e.g. an array of entries, an ISO string, a plain object) before returning. Note: removing `jsonSerializable: true` also disables `agent` exposure; if you need MCP, you must use a JSON-safe shape.

## Source

`packages/devframe/src/rpc/serialization.ts`
29 changes: 29 additions & 0 deletions devframe/docs/errors/DF0021.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
outline: deep
---

# DF0021: RPC Function Already Registered

> Package: `devframe`

> Migrated from `DTK0001`.

## Message

> RPC function "`{name}`" is already registered

## Cause

`ctx.rpc.register()` was called twice with the same `name`. RPC names must be unique within a devtool.

## Fix

Either give the second registration a distinct name, or pass `force: true` to overwrite the previous one (e.g. during HMR-driven re-registration).

```ts
ctx.rpc.register(defineRpcFunction({ name: 'my-plugin:fn', handler: () => 1 }), true /* force */)
```

## Source

`packages/devframe/src/rpc/collector.ts`
25 changes: 25 additions & 0 deletions devframe/docs/errors/DF0022.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
outline: deep
---

# DF0022: RPC Function Not Registered (Update)

> Package: `devframe`

> Migrated from `DTK0002`.

## Message

> RPC function "`{name}`" is not registered. Use register() to add new functions.

## Cause

`ctx.rpc.update()` was called for a function that was never registered. `update()` is for replacing an existing definition.

## Fix

Call `ctx.rpc.register()` first, or pass `force: true` to `update()` to register-or-replace in one call.

## Source

`packages/devframe/src/rpc/collector.ts`
25 changes: 25 additions & 0 deletions devframe/docs/errors/DF0023.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
outline: deep
---

# DF0023: RPC Function Not Registered (Get)

> Package: `devframe`

> Migrated from `DTK0003`.

## Message

> RPC function "`{name}`" is not registered

## Cause

A consumer asked for the schema or handler of a function that has never been registered with `ctx.rpc.register()`.

## Fix

Confirm the function name matches a registration. RPC names are namespaced — typos in the prefix are a common cause.

## Source

`packages/devframe/src/rpc/collector.ts`
25 changes: 25 additions & 0 deletions devframe/docs/errors/DF0024.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
outline: deep
---

# DF0024: Missing RPC Handler

> Package: `devframe`

> Migrated from `DTK0004`.

## Message

> Either handler or setup function must be provided for RPC function "`{name}`"

## Cause

The RPC definition has neither a `handler` nor a `setup` returning `{ handler }`. devframe has nothing to invoke when the function is called.

## Fix

Add either `handler: ...` directly on the definition, or `setup: ctx => ({ handler: ... })` if the handler depends on context.

## Source

`packages/devframe/src/rpc/handler.ts`
25 changes: 25 additions & 0 deletions devframe/docs/errors/DF0025.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
outline: deep
---

# DF0025: Function Not in Dump Store

> Package: `devframe`

> Migrated from `DTK0005`.

## Message

> Function "`{name}`" not found in dump store

## Cause

A static-mode client called an RPC function that was not baked into the build dump. This usually means the function was added after the dump was generated, or its name changed between build and runtime.

## Fix

Re-run `createBuild` to regenerate the dump, or check that the call site uses the same name registered on the server.

## Source

`packages/devframe/src/rpc/dumps.ts`
35 changes: 35 additions & 0 deletions devframe/docs/errors/DF0026.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
outline: deep
---

# DF0026: No Dump Match

> Package: `devframe`

> Migrated from `DTK0006`.

## Message

> No dump match for "`{name}`" with args: `{args}`

## Cause

A static-mode client called an RPC function with arguments that don't match any pre-computed record, and no `fallback` was set on the dump.

## Fix

Either widen the function's `dump.inputs` to cover the requested arguments, or provide `dump.fallback` so unmatched calls resolve to a default value instead of throwing.

```ts
defineRpcFunction({
name: 'my-plugin:get',
dump: {
inputs: [['known-id']],
fallback: null,
},
})
```

## Source

`packages/devframe/src/rpc/dumps.ts`
25 changes: 25 additions & 0 deletions devframe/docs/errors/DF0027.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
outline: deep
---

# DF0027: Invalid Dump Configuration

> Package: `devframe`

> Migrated from `DTK0007`.

## Message

> Function "`{name}`" with type "`{type}`" cannot have dump configuration. Only "static" and "query" types support dumps.

## Cause

A `dump` field was attached to an `'action'` or `'event'` function. These types perform side effects rather than returning queryable data — there is nothing meaningful to pre-compute.

## Fix

Drop the `dump` field, or change the function `type` to `'static'` / `'query'` if pre-computation is appropriate.

## Source

`packages/devframe/src/rpc/validation.ts`
25 changes: 25 additions & 0 deletions devframe/docs/errors/DF0028.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
outline: deep
---

# DF0028: Snapshot Type Mismatch

> Package: `devframe`

> Migrated from `DTK0008`.

## Message

> Function "`{name}`" with type "`{type}`" cannot use `snapshot: true`. Only "query" functions support this sugar; "static" functions have equivalent default behavior already.

## Cause

`snapshot: true` is sugar for "query in dev, single baked snapshot in build". It is only meaningful on `'query'` functions — `'static'` already has equivalent default behavior, and `'action'` / `'event'` have nothing to snapshot.

## Fix

Remove `snapshot: true`, or change the function `type` to `'query'`.

## Source

`packages/devframe/src/rpc/validation.ts`
10 changes: 10 additions & 0 deletions devframe/docs/errors/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,13 @@ Emitted by `devframe` — framework-neutral host / shared-state / auth surface.
| [DF0016](./DF0016) | error | Agent Resource Already Registered | — |
| [DF0017](./DF0017) | error | MCP Server Start Failure | — |
| [DF0018](./DF0018) | warn | `ctx.logs` Deprecated | — |
| [DF0019](./DF0019) | error | Agent Requires JSON-Serializable RPC | — |
| [DF0020](./DF0020) | error | Non-JSON Value in JSON-Serializable RPC | — |
| [DF0021](./DF0021) | error | RPC Function Already Registered | DTK0001 |
| [DF0022](./DF0022) | error | RPC Function Not Registered (Update) | DTK0002 |
| [DF0023](./DF0023) | error | RPC Function Not Registered (Get) | DTK0003 |
| [DF0024](./DF0024) | error | Missing RPC Handler | DTK0004 |
| [DF0025](./DF0025) | error | Function Not in Dump Store | DTK0005 |
| [DF0026](./DF0026) | error | No Dump Match | DTK0006 |
| [DF0027](./DF0027) | error | Invalid Dump Configuration | DTK0007 |
| [DF0028](./DF0028) | error | Snapshot Type Mismatch | DTK0008 |
Loading
Loading