mastra-ai/mastra · error
crossProcessPubSub requires a pubsub instance
Error message
crossProcessPubSub requires a pubsub instance
What it means
createMastraCodeAgentController() computes crossProcessPubSub from config.crossProcessPubSub or from enabling unix-socket pubsub when no pubsub was configured. Cross-process signaling requires an actual pubsub instance; if the flag is enabled but signalsPubSub is undefined (no config.pubsub and unix-socket path unavailable, e.g. on win32), the controller refuses to start.
Source
Thrown at mastracode/sdk/src/index.ts:507
const resourceIdOverride = getResourceIdOverride(project.rootPath, configDir);
if (resourceIdOverride) {
project.resourceId = resourceIdOverride;
project.resourceIdOverride = true;
}
// Stable session id unique to this project/resource, and a machine-bound owner
// id. resourceId encodes root path + git identity and honors overrides, so it
// is the right input for scoping the session to the cwd/project.
const sessionId = `mastracode-session-${shortHash(project.resourceId)}`;
const ownerId = `mastracode-${shortHash(`${hostname()}\0${project.rootPath}`)}`;
const configuredPubSub = config?.pubsub;
const useUnixSocketPubSub =
(config?.unixSocketPubSub ?? globalSettings.signals?.unixSocketPubSub ?? false) && process.platform !== 'win32';
const signalsPubSub = configuredPubSub ?? (useUnixSocketPubSub ? createSignalsPubSub(project.resourceId) : undefined);
const crossProcessPubSub = config?.crossProcessPubSub ?? (!configuredPubSub && useUnixSocketPubSub);
if (crossProcessPubSub && !signalsPubSub) {
throw new Error('crossProcessPubSub requires a pubsub instance');
}
// Storage. An injected instance is used as-is — no connection test, no
// LibSQL fallback: if the injected store fails, that's a hard error.
const injectedStorage = isInjectedStorageInstance(config?.storage) ? config.storage : undefined;
const storageConfig = injectedStorage
? undefined
: ((config?.storage as StorageConfig | undefined) ??
getStorageConfig(project.rootPath, globalSettings.storage, configDir));
const storageResult: StorageResult = injectedStorage
? { storage: injectedStorage, backend: resolveInjectedStorageBackend(injectedStorage, config?.storageBackend) }
: await createStorage(storageConfig!);
const storageWarning = storageResult.warning;
// Observability storage (DuckDB — separate file for OLAP-style trace/score/feedback queries).
// Local tracing is opt-in via `/observability local on`. When disabled, the
// MastraStorageExporter is omitted entirely so traces never fall through to
// the default libsql backend.View on GitHub (pinned to 75dd419e61)
Solutions
- Provide an explicit instance: createMastraCodeAgentController({ crossProcessPubSub: true, pubsub: myPubSub }).
- Remove crossProcessPubSub/unixSocketPubSub if you only need single-process signaling.
- On Windows, switch to a platform-agnostic pubsub implementation instead of unixSocketPubSub.
Example fix
// before
createMastraCodeAgentController({ crossProcessPubSub: true });
// after
createMastraCodeAgentController({ crossProcessPubSub: true, pubsub: createMyPubSub() }); Defensive patterns
Strategy: validation
Validate before calling
const wantsCrossProcess = config?.crossProcessPubSub || config?.unixSocketPubSub;
if (wantsCrossProcess && !config?.pubsub && process.platform === 'win32') {
throw new Error('crossProcessPubSub requires an explicit pubsub instance on this platform');
} Type guard
function hasPubSub(c: unknown): c is { pubsub: NonNullable<MastraCodeConfig['pubsub']> } {
return c != null && typeof c === 'object' && 'pubsub' in c && c.pubsub != null;
} Try / catch
try {
controller = await createMastraCodeAgentController(cfg);
} catch (err) {
if (err instanceof Error && err.message.includes('crossProcessPubSub requires a pubsub instance')) {
controller = await createMastraCodeAgentController({ ...cfg, pubsub: createDefaultPubSub() });
} else { throw err; }
} Prevention
- Provide config.pubsub whenever crossProcessPubSub (or unixSocketPubSub) is enabled.
- On Windows, use a TCP/named-pipe pubsub instead of unixSocketPubSub.
- Gate cross-process options behind platform checks in shared config files.
When it happens
Trigger: Setting config.crossProcessPubSub: true without config.pubsub; or setting unixSocketPubSub: true while process.platform === 'win32' (the useUnixSocketPubSub guard disables socket creation, leaving signalsPubSub undefined).
Common situations: Copy-pasting a Unix-only multi-process config onto Windows; enabling crossProcessPubSub in a config file without wiring a pubsub implementation; forgetting that unixSocketPubSub alone does not create a pubsub on non-Unix platforms.
Related errors
- OrchestrationWorker requires a pull-capable PubSub, but the
- No Pubsub adapter configured on the Mastra instance
- Mastra instance with pubsub is required for workflow executi
- AcpAgent does not support resuming suspended generate calls
- ACP prompt stopped before completing: ${response.stopReason}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/605031c178e5a75a.
Report an issue: GitHub.