Duplicate Code Opportunity
Summary
- Pattern: Identical domain-blocked analysis loop (classify domain vs port vs other, emit diagnostic messages, suggest
--allow-domains fix) copy-pasted between two error-handling paths with only the log level differing (logger.error vs logger.warn).
- Locations:
src/container-lifecycle.ts lines 524–564 (startup error path) and 644–680 (post-run warning path)
- Impact: ~37 duplicated lines; any fix to the diagnostic format or allowlist-check logic must be made in two places
Evidence
Copy 1 — handleContainerStartError() (lines 524–564), uses logger.error:
const missingDomains: string[] = [];
const portIssues: BlockedTarget[] = [];
blockedTargets.forEach(blocked => {
const isAllowed = allowedDomains.some(allowed =>
blocked.domain === allowed || blocked.domain.endsWith('.' + allowed)
);
if (!isAllowed) {
logger.error(` - Blocked: \$\{blocked.target} (domain not in allowlist)`);
missingDomains.push(blocked.domain);
} else if (blocked.port && blocked.port !== '80' && blocked.port !== '443') {
logger.error(` - Blocked: \$\{blocked.target} (port \$\{blocked.port} not allowed, only 80 and 443 are permitted)`);
portIssues.push(blocked);
} else {
logger.error(` - Blocked: \$\{blocked.target}`);
}
});
logger.error('Allowed domains:');
allowedDomains.forEach(domain => { logger.error(` - Allowed: \$\{domain}`); });
if (missingDomains.length > 0) {
logger.error(`To fix domain issues: --allow-domains "\$\{[...allowedDomains, ...missingDomains].join(',')}"`);
}
if (portIssues.length > 0) {
logger.error('To fix port issues: Use standard ports 80 (HTTP) or 443 (HTTPS)');
}
Copy 2 — runAgentCommand() (lines 644–680), uses logger.warn:
Structurally identical; only differences are logger.warn instead of logger.error and the absence of the final throw.
Suggested Refactoring
Extract a reportBlockedDomains helper in src/container-lifecycle.ts (or a new src/blocked-domain-reporter.ts):
interface BlockedDomainReport {
missingDomains: string[];
portIssues: BlockedTarget[];
}
function reportBlockedDomains(
blockedTargets: BlockedTarget[],
allowedDomains: string[],
log: (msg: string) => void, // pass logger.error or logger.warn
): BlockedDomainReport {
const missingDomains: string[] = [];
const portIssues: BlockedTarget[] = [];
blockedTargets.forEach(blocked => {
const isAllowed = allowedDomains.some(
a => blocked.domain === a || blocked.domain.endsWith('.' + a)
);
if (!isAllowed) {
log(` - Blocked: \$\{blocked.target} (domain not in allowlist)`);
missingDomains.push(blocked.domain);
} else if (blocked.port && blocked.port !== '80' && blocked.port !== '443') {
log(` - Blocked: \$\{blocked.target} (port \$\{blocked.port} not allowed, only 80 and 443 are permitted)`);
portIssues.push(blocked);
} else {
log(` - Blocked: \$\{blocked.target}`);
}
});
log('Allowed domains:');
allowedDomains.forEach(d => log(` - Allowed: \$\{d}`));
if (missingDomains.length > 0)
log(`To fix domain issues: --allow-domains "\$\{[...allowedDomains, ...missingDomains].join(',')}"`);
if (portIssues.length > 0)
log('To fix port issues: Use standard ports 80 (HTTP) or 443 (HTTPS)');
return { missingDomains, portIssues };
}
Both call sites then become a single reportBlockedDomains(blockedTargets, allowedDomains, logger.error) / logger.warn call.
Affected Files
src/container-lifecycle.ts — lines 524–564 and 644–680
Effort Estimate
Low
Detected by Duplicate Code Detector workflow. Run date: 2026-05-05
Generated by Duplicate Code Detector · ● 594.5K · ◷
Duplicate Code Opportunity
Summary
--allow-domainsfix) copy-pasted between two error-handling paths with only the log level differing (logger.errorvslogger.warn).src/container-lifecycle.tslines 524–564 (startup error path) and 644–680 (post-run warning path)Evidence
Copy 1 —
handleContainerStartError()(lines 524–564), useslogger.error:Copy 2 —
runAgentCommand()(lines 644–680), useslogger.warn:Structurally identical; only differences are
logger.warninstead oflogger.errorand the absence of the finalthrow.Suggested Refactoring
Extract a
reportBlockedDomainshelper insrc/container-lifecycle.ts(or a newsrc/blocked-domain-reporter.ts):Both call sites then become a single
reportBlockedDomains(blockedTargets, allowedDomains, logger.error)/logger.warncall.Affected Files
src/container-lifecycle.ts— lines 524–564 and 644–680Effort Estimate
Low
Detected by Duplicate Code Detector workflow. Run date: 2026-05-05