paperclipai/paperclip · error · Error
${path} must be a non-empty string
Error message
${path} must be a non-empty string What it means
The text() helper validates that a field at a given path is a string with non-empty trimmed content. It throws '<path> must be a non-empty string' when the value is missing, not a string, or only whitespace. Used for required identifiers like agentVersion and profileId in eval-session profiles.
Source
Thrown at packages/paperclip-runner/src/cli/eval-session-contract.ts:103
agentTurns: number;
providerRequests: number;
inputTokens: number;
outputTokens: number;
cachedInputTokens: number;
reasoningTokens: number;
providerReportedCostNanodollars: number;
}
function object(value: unknown, path: string): Record<string, unknown> {
if (typeof value !== "object" || value === null || Array.isArray(value)) {
throw new Error(`${path} must be an object`);
}
return value as Record<string, unknown>;
}
function text(value: unknown, path: string): string {
if (typeof value !== "string" || value.trim().length === 0) {
throw new Error(`${path} must be a non-empty string`);
}
return value;
}
function positiveInteger(value: unknown, path: string): number {
if (!Number.isSafeInteger(value) || Number(value) <= 0) {
throw new Error(`${path} must be a positive safe integer`);
}
return Number(value);
}
export function expectedEvalSessionDriver(
provider: EvalSessionProvider,
): EvalSessionDriver {
return provider === "opencode"
? "opencode_server"
: provider === "claude_managed"
? "claude_managed_agents_api"View on GitHub (pinned to 01ad858492)
Solutions
- Populate the field named in the error path with a non-empty trimmed string
- Check the producer/config for empty template interpolation or missing keys
- Add the missing key to the request payload per the eval-session schema
- If the field is genuinely optional upstream, stop routing it through this required-field contract
Example fix
// before
const req = { schema: SCHEMA, managedProfile: { betaVersion: 'managed-agents-2026-04-01', agentVersion: '' } };
// after
const req = { schema: SCHEMA, managedProfile: { betaVersion: 'managed-agents-2026-04-01', agentVersion: '42' } }; Defensive patterns
Strategy: validation
Validate before calling
function requireNonEmptyString(v, name) {
if (typeof v !== 'string' || v.trim().length === 0) throw new Error(`${name} must be a non-empty string`);
return v;
}
requireNonEmptyString(req.managedProfile?.agentVersion, 'agentVersion'); Type guard
function isNonEmptyString(v) {
return typeof v === 'string' && v.trim().length > 0;
} Try / catch
try {
const request = parseEvalSessionRequest(raw);
} catch (err) {
if (err.message.includes('must be a non-empty string')) {
const field = err.message.split(' ')[0];
throw new RequestValidationError(`Missing required field: ${field}`, { cause: err });
}
throw err;
} Prevention
- Validate all identifier fields at request-construction time, not at the boundary
- Guard against empty template interpolation in config-driven payloads
- Run a pre-submission check that trims and asserts every required string
- Keep field names in sync with the contract after renames (use exported constants where possible)
When it happens
Trigger: Any required string field validated via text() — e.g. request.managedProfile.agentVersion, request.managedProfile.profileId, request.agentCoreProfile.profileId/region — is undefined, null, a non-string type, or ""/whitespace-only.
Common situations: Caller omits an identifier field; a template variable interpolates to empty; upstream returns null for a profile id; field renamed so the key no longer matches.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- ${path} must be an object
- ${path} must be a positive safe integer
- ${path} must be a positive finite number
- request.managedProfile.betaVersion is not qualified
- request.managedProfile.agentVersion must be a canonical posi
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-02).
Data as JSON: /api/errors/3c4aab493877ab84.
Report an issue: GitHub.