can1357/oh-my-pi · error · ConfigError

Schema produced no default value

Error message

Schema produced no default value

What it means

createDefault builds a default config by invoking the ArkType schema with an empty object ({}) and, failing that, with undefined. If both applications return an Error (the schema has required fields with no defaults), no default value can be synthesized and it throws a ConfigError with stage 'createDefault'. Reached via loadOrDefault/loadOrDefaultAsync when the config file is missing.

Source

Thrown at packages/coding-agent/src/config/config-file.ts:238

	withValidation(name: string, validate: (value: T) => void): this {
		const prev = this.#auxValidate;
		this.#auxValidate = (value: T) => {
			prev?.(value);
			try {
				validate(value);
			} catch (error) {
				throw new ConfigError(this.id, undefined, { err: error, stage: `Validate(${name})` });
			}
		};
		return this;
	}

	createDefault(): T {
		const parsed = this.schema({});
		if (!(parsed instanceof Error)) return parsed as T;
		const fallback = this.schema(undefined);
		if (!(fallback instanceof Error)) return fallback as T;
		throw new ConfigError(this.id, undefined, {
			err: new Error("Schema produced no default value"),
			stage: "createDefault",
		});
	}

	#storeCache(result: LoadResult<T>): LoadResult<T> {
		this.#cache = result;
		return result;
	}

	#parseContent(content: string): LoadResult<T> {
		try {
			let parsed: unknown;
			const readPath = this.#resolveReadPath();
			if (readPath.endsWith(".json") || readPath.endsWith(".jsonc")) {
				parsed = JSONC.parse(content);
			} else if (readPath.endsWith(".yml") || readPath.endsWith(".yaml")) {
				parsed = YAML.parse(content);

View on GitHub (pinned to 9690622007)

Solutions

  1. Add default values to required fields in the schema (e.g. `foo: type("string").default("bar")`) so `schema({})` succeeds
  2. Make required fields optional so `schema(undefined)` yields a fallback
  3. If defaults can't be expressed in the schema, construct the default object manually instead of relying on loadOrDefault

Example fix

// before
const schema = type({ name: "string", port: "number" });
// after
const schema = type({ name: type("string").default("agent"), port: type("number").default(8080) });
Defensive patterns

Strategy: validation

Validate before calling

// verify the schema can synthesize a default before relying on loadOrDefault
const probe = schema({});
if (probe instanceof Error) {
	throw new Error("Schema cannot produce defaults; add .default(...) to required fields");
}

Type guard

function schemaHasDefault(schema: Type): boolean {
	return !(schema({}) instanceof Error) || !(schema(undefined) instanceof Error);
}

Try / catch

let value: T;
try {
	value = configFile.createDefault();
} catch (err) {
	if (err instanceof ConfigError && err.stage === "createDefault") {
		value = hardcodedFallbackDefault; // manually constructed default
	} else throw err;
}

Prevention

When it happens

Trigger: Calling loadOrDefault/loadOrDefaultAsync when the config file does not exist, while the schema requires properties that neither `{}` nor `undefined` can satisfy — i.e. required fields without `.default(...)` or optional markers.

Common situations: A fresh install or wiped config directory where the library is expected to bootstrap defaults, but the schema was written with mandatory fields lacking defaults, so bootstrapping fails.

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/d12d579d63645c3c. Report an issue: GitHub.