fix(storage): create the config file's own dir in save_config

save_config() ran os.makedirs(SERVERKIT_CONFIG_DIR) unconditionally rather
than the directory of the file it actually writes (cls.CONFIG_FILE). When a
caller overrides CONFIG_FILE (test_storage_secret_encrypted_at_rest points it
at a pytest tmp dir), creating the real config dir failed on the sandboxed CI
runner and — because the surrounding except swallows it and returns
{success: False} — the file was never written, surfacing as a confusing
FileNotFoundError. Now makedirs(dirname(CONFIG_FILE)); production behavior is
unchanged (there dirname(CONFIG_FILE) == SERVERKIT_CONFIG_DIR). 8/8 encryption
tests pass; full backend suite was 241 passed / 1 failed -> now green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Juan DenisandClaude Opus 4.8 committed 2026-06-15 23:55:03 -04:00
1 parent ad7e38c203
commit 2483541356
1 file changed
+8 -1
@@ -84,7 +84,14 @@ class StorageProviderService:
def save_config(cls, config: Dict) -> Dict:
"""Save storage provider configuration."""
try:
os.makedirs(paths.SERVERKIT_CONFIG_DIR, exist_ok=True)
# Ensure the parent of the file we actually write exists. Using
# cls.CONFIG_FILE (not the hardcoded SERVERKIT_CONFIG_DIR) honors a
# CONFIG_FILE override — e.g. tests pointing it at a tmp dir — and
# is identical in production, where CONFIG_FILE lives in
# SERVERKIT_CONFIG_DIR. Previously this tried to create the real
# config dir unconditionally, which raised on a sandboxed CI runner
# and (because the except below swallows it) left the file unwritten.
os.makedirs(os.path.dirname(cls.CONFIG_FILE) or '.', exist_ok=True)
# Merge with existing config to preserve unmasked secrets
existing = cls.get_config()