can1357/oh-my-pi · error · Error

Failed to read settings config ${filePath}: ${String(result.

Error message

Failed to read settings config ${filePath}: ${String(result.error)}

What it means

Thrown when reading the settings YAML fails at the I/O level (kind === "unreadable") — distinct from parse-invalid. The file exists in the expected location but could not be read, and the underlying OS error is stringified into the message.

Source

Thrown at packages/coding-agent/src/config/settings.ts:1496

			path: filePath,
			backupPath,
			error: String(result.error),
		});
		return { ...result, backupPath };
	}

	#unwrapYamlLoadResult(filePath: string, result: YamlLoadResult): RawSettings | null {
		switch (result.kind) {
			case "missing":
				return null;
			case "loaded":
				return result.settings;
			case "invalid":
				throw new Error(
					`Settings config is invalid: ${filePath}${result.backupPath ? ` (moved to ${result.backupPath})` : ""}: ${String(result.error)}`,
				);
			case "unreadable":
				throw new Error(`Failed to read settings config ${filePath}: ${String(result.error)}`);
		}
	}

	async #readExistingMainYaml(quarantineInvalid: boolean): Promise<MainYamlReadResult> {
		if (!this.#configPath) return { settings: null, configPath: null };
		for (const filename of MAIN_CONFIG_FILENAMES) {
			const configPath = path.join(this.#agentDir, filename);
			const loaded = quarantineInvalid
				? await this.#loadYamlIfPresentForStartup(configPath)
				: this.#unwrapYamlLoadResult(configPath, await this.#loadYamlIfPresent(configPath, false));
			if (loaded) return { settings: loaded, configPath };
		}
		return {
			settings: null,
			configPath: path.join(this.#agentDir, MAIN_CONFIG_FILENAMES[0]),
		};
	}

View on GitHub (pinned to 9690622007)

Solutions

  1. Check the embedded OS error: fix permissions (chmod/chown) for EACCES
  2. Remove or rename the directory occupying the path if the error is EISDIR
  3. Verify the filesystem/mount is healthy and retry

Example fix

// before
$ ls -l ~/.omp/settings.yaml  # owned by root
// after
$ sudo chown $USER ~/.omp/settings.yaml
Defensive patterns

Strategy: try-catch

Validate before calling

async function settingsReadable(path) {
  try { await fs.promises.access(path, fs.constants.R_OK); return true; } catch { return false; }
}

Try / catch

try { const s = await loadSettings(); } catch (e) {
  if (String(e).startsWith('Failed to read settings config')) {
    logger.error('Settings file unreadable; check permissions/path', { error: String(e) });
  } else throw e;
}

Prevention

When it happens

Trigger: fs read of settings.yaml rejects with EACCES (no read permission), EISDIR (a directory named settings.yaml exists), EIO, or similar non-ENOENT errors.

Common situations: Permissions changed by another tool; a directory accidentally created where the file should be; failing disk or network mount holding the home directory.

Related errors


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