nexu-io/open-design · error
connector refresh source requires connector metadata
Error message
connector refresh source requires connector metadata
What it means
Raised by executeRefreshSource() when source.type === 'connector_tool' but source.connector is undefined. Per the LiveArtifactSource contract, a connector_tool source must carry connector metadata (connectorId, toolName, optional accountLabel) so the refresh knows which connector tool to re-execute; the absence means the artifact's data.json is structurally invalid.
Source
Thrown at apps/daemon/src/live-artifacts/refresh-service.ts:87
function isSupportedSource(source: LiveArtifactSource | undefined): source is LiveArtifactSource {
if (source === undefined) return false;
return source.type === 'local_file' || source.type === 'daemon_tool' || source.type === 'connector_tool';
}
function hasRefreshPermission(source: LiveArtifactSource): boolean {
return source.refreshPermission === 'manual_refresh_granted_for_read_only';
}
async function executeRefreshSource(options: {
projectsRoot: string;
projectId: string;
source: LiveArtifactSource;
signal: AbortSignal;
}): Promise<BoundedJsonObject> {
const { projectsRoot, projectId, source, signal } = options;
if (source.type === 'connector_tool') {
const connector = source.connector;
if (connector === undefined) throw new Error('connector refresh source requires connector metadata');
const result = await connectorService.execute(
{
connectorId: connector.connectorId,
toolName: connector.toolName,
input: source.input,
...(connector.accountLabel === undefined ? {} : { expectedAccountLabel: connector.accountLabel }),
},
{ projectsRoot, projectId, purpose: 'artifact_refresh', signal },
);
if (result.output === null || typeof result.output !== 'object' || Array.isArray(result.output)) {
throw new Error('connector refresh output must be a JSON object');
}
return result.output;
}
if (source.type !== 'daemon_tool' && source.type !== 'local_file') {
throw new Error(`refresh source ${source.type} is not supported yet`);
}
return executeLocalDaemonRefreshSource({ projectsRoot, projectId, source, signal });View on GitHub (pinned to 5be4028344)
Solutions
- Before refreshing, validate the source: if source.type === 'connector_tool' require source.connector to be present, else mark the artifact non-refreshable.
- Re-run the original connector tool to regenerate the artifact with full source metadata.
- Add a backfill migration that reconstructs connector metadata from provenance/history for existing artifacts.
Example fix
// before
if (source.type === 'connector_tool') {
const connector = source.connector;
if (connector === undefined) throw new Error('connector refresh source requires connector metadata');
}
// after
if (source.type === 'connector_tool' && !source.connector) {
return { ok: false, reason: 'source_missing_connector_metadata' };
}
if (source.type === 'connector_tool') {
const connector = source.connector!;
// ... proceed
} Defensive patterns
Strategy: type-guard
Validate before calling
import type { LiveArtifactSource } from '@open-design/contracts';
function isRefreshableConnectorSource(source: LiveArtifactSource): boolean {
return source.type !== 'connector_tool' || source.connector !== undefined;
}
if (!isRefreshableConnectorSource(source)) {
return { ok: false, reason: 'source_missing_connector_metadata' };
} Type guard
import type { LiveArtifactSource } from '@open-design/contracts';
function hasConnectorMetadata(source: LiveArtifactSource): source is LiveArtifactSource & { connector: { connectorId: string; toolName: string } } {
return source.type === 'connector_tool'
&& source.connector !== undefined
&& typeof source.connector.connectorId === 'string'
&& typeof source.connector.toolName === 'string';
} Try / catch
try {
return await executeRefreshSource({ projectsRoot, projectId, source, signal });
} catch (err) {
if (err instanceof Error && err.message === 'connector refresh source requires connector metadata') {
return { ok: false, reason: 'source_missing_connector_metadata' };
}
throw err;
} Prevention
- Validate connector_tool sources carry connector metadata before scheduling a refresh.
- Backfill connector metadata for existing artifacts after schema/provider changes.
- Re-run the originating connector tool to regenerate a source with full metadata.
When it happens
Trigger: Refreshing a live artifact whose stored LiveArtifactSource has type 'connector_tool' but no connector object — e.g. it was created by an older writer, a migration dropped the field, or a tool produced a source JSON missing the connector block.
Common situations: Schema migration that did not backfill connector metadata on existing connector_tool artifacts; a custom tool that wrote data.json without the connector block; partial write interrupted before connector was attached; connector disconnected and its metadata stripped from the source.
Related errors
- ${task.folder}: spritesheet too small (${bytes.length} bytes
- ${task.folder}: spritesheet is not webp/png/gif
- CONNECTOR_TOOL_NOT_FOUND
- comment note required
- zip entry size mismatch: ${relPath}
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/2480c749b9d4ece8.
Report an issue: GitHub.