Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion perry/internal/src/commands/entrypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ export const runEntrypoint = async () => {
return;
}
console.log("[entrypoint] Running workspace initialization...");
await runInit();
try {
await runInit();
} catch (error) {
console.log(`[entrypoint] Initialization failed (non-fatal): ${(error as Error).message}`);
console.log("[entrypoint] SSH will still start - connect to debug the issue");
}
Comment on lines +23 to +28

This comment was marked as outdated.

console.log("[entrypoint] Starting SSH daemon...");
await startSshd();
void monitorServices();
Expand Down
12 changes: 9 additions & 3 deletions perry/internal/src/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ const cloneRepository = async (
return;
}

const repoName = repoUrl.replace(/\/+$/, "").split("/").pop() ?? "repo";
const cleanRepoName = repoName.replace(/\.git$/, "");
const repoPath = path.join(workspaceHome, cleanRepoName);
if (await pathExists(repoPath)) {
console.log(`Repository directory '${cleanRepoName}' already exists. Skipping clone.`);
await configureGitSshKey(workspaceHome, repoPath, runtimeConfig?.ssh?.selectedKey ?? "");
return;
}
Comment on lines +86 to +93
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: A new check for an existing repository directory causes an infinite initialization loop if a post-clone step fails, preventing the workspace from ever successfully starting up.
Severity: CRITICAL | Confidence: High

🔍 Detailed Analysis

A new check for an existing repository directory can lead to an infinite initialization loop. If a post-clone step, such as runBootstrapScripts(), fails, the .workspace-initialized marker file is not created. On subsequent restarts, the new check at lines 86-93 will find the existing repository directory and cause cloneRepository() to return early. The initialization process will then re-run the subsequent steps, which will fail again at the same point. This leaves the workspace in a permanently broken state, unable to complete initialization without manual user intervention to remove the repository directory.

💡 Suggested Fix

The logic should be adjusted to handle this semi-initialized state. Instead of returning early if the repository directory exists, consider either deleting the directory to allow a fresh clone or making the subsequent initialization steps more robust to this condition. The previous behavior, which would fail on the git clone command itself, was more explicit.

🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: perry/internal/src/commands/init.ts#L86-L93

Potential issue: A new check for an existing repository directory can lead to an
infinite initialization loop. If a post-clone step, such as `runBootstrapScripts()`,
fails, the `.workspace-initialized` marker file is not created. On subsequent restarts,
the new check at lines 86-93 will find the existing repository directory and cause
`cloneRepository()` to return early. The initialization process will then re-run the
subsequent steps, which will fail again at the same point. This leaves the workspace in
a permanently broken state, unable to complete initialization without manual user
intervention to remove the repository directory.

Did we get this right? 👍 / 👎 to inform future reviews.
Reference ID: 8300857


console.log("=== Configuration Debug Info ===");
console.log(`Repository URL: ${repoUrl}`);
await logRuntimeConfigContents(runtimeConfigPath);
Expand Down Expand Up @@ -143,9 +152,6 @@ const cloneRepository = async (
}
console.log("Repository clone completed.");

const repoName = repoUrl.replace(/\/+$/, "").split("/").pop() ?? "repo";
const cleanRepoName = repoName.replace(/\.git$/, "");
const repoPath = path.join(workspaceHome, cleanRepoName);
if (await pathExists(repoPath)) {
await configureGitSshKey(workspaceHome, repoPath, selectedKey);
}
Expand Down