jackwener/OpenCLI · error · Error
Not a git repository
Error message
Not a git repository
What it means
This MALFORMED_RESULT error is produced by the huodongxing CLI's extractEventRowsPayload when the scraper did find event card elements in the returned page, but none of them could be converted into stable event rows. Extraction requires each card to yield an event link matching /event/<id> plus a non-empty title; when the markup no longer matches that contract, the library reports the payload as malformed rather than returning empty or partial data. It signals a site-side markup change (or bot-wall interstitial rendering card-like nodes), not a caller mistake.
Source
Thrown at autoresearch/engine.ts:90
private bestMetric: number = 0;
private currentMetric: number = 0;
private iteration: number = 0;
constructor(config: AutoResearchConfig, logPath: string, callbacks: EngineCallbacks) {
this.config = config;
this.logger = new Logger(logPath);
this.callbacks = callbacks;
}
private log(msg: string): void {
this.callbacks.onStatus?.(msg);
}
/** Phase 0: Precondition checks */
private checkPreconditions(): void {
// Git repo exists
try { execStrict('git rev-parse --git-dir'); }
catch { throw new Error('Not a git repository'); }
// Clean working tree
const status = exec('git status --porcelain');
if (status) throw new Error(`Working tree not clean:\n${status}`);
// No stale locks
if (existsSync(join(ROOT, '.git', 'index.lock'))) {
throw new Error('Stale .git/index.lock found — remove it first');
}
// Not detached HEAD
try { execStrict('git symbolic-ref HEAD'); }
catch { throw new Error('Detached HEAD — checkout a branch first'); }
}
/** Phase 5: Run verify command and extract metric */
private runVerify(): number | null {
this.log(' verify...');View on GitHub (pinned to 49907e53dc)
Solutions
- Wait and retry the request from the same browser session — confirm the page actually shows real event cards (not a busy/interstitial page) via a screenshot or DOM dump.
- Inspect the current card markup and update the extraction selectors/logic to match the new '/event/<id>' link shape and title element.
- Dump the failing HTML to verify whether titles are empty because JS hasn't run; if so, wait for hydration (e.g. waitForSelector on the title) before extracting.
- If the site changed its URL scheme permanently, update the expected pattern (regex) for event links inside extractEventRowsPayload.
Example fix
// before
const links = card.querySelectorAll('a[href^="/event/"]');
if (!links.length) throw malformed;
// after
// accept new absolute/relative event link shapes and wait for titles
await page.waitForSelector('[data-event-title]:not(:empty)');
const links = card.querySelectorAll('a[href*="/event/"]'); Defensive patterns
Strategy: validation
Validate before calling
const cards = document.querySelectorAll('.event-card');
if (cards.length > 0 && !Array.from(cards).some(c => c.querySelector('a[href*="/event/"]')?.textContent?.trim())) {
console.warn('Card markup drift detected: no /event/<id> links with titles — abort before calling extractEventRows');
} Type guard
function isStableEventRow(row: unknown): row is { id: string; title: string } {
return typeof row === 'object' && row !== null &&
typeof (row as any).id === 'string' && /^.+/.test((row as any).id) &&
typeof (row as any).title === 'string' && (row as any).title.trim().length > 0;
} Try / catch
try {
const rows = await extractEventRows();
} catch (err) {
if (err.code === 'MALFORMED_RESULT') {
log.warn('Huodongxing markup changed:', err.hint);
// fall back to raw HTML dump for manual selector update
} else throw err;
} Prevention
- Add a screenshot/DOM snapshot of the events page to your scraping debug artifacts each run so markup drift is visible.
- Write a smoke test against a saved HTML fixture of the events page that asserts rows still extract.
- Keep the '/event/<id>' link pattern centralized so a route change is a one-line fix.
- Wait for client-side hydration (title elements non-empty) before extracting.
When it happens
Trigger: Calling extractEventRows (which delegates to extractEventRowsPayload) when the DOM query returns cards.length > 0 but zero cards match the '/event/<id>' link + non-empty title pattern, e.g. after Huodongxing renames routes, wraps links, or lazy-renders titles.
Common situations: Huodongxing ships a front-end redesign or A/B markup change; a CDN/anti-bot edge page injects card-like HTML without real event links; titles are rendered via images or client-side JS that hasn't executed in the scraping session.
Related errors
- Working tree not clean: ${status}
- Trip.com attraction DOM extraction returned malformed rows
- Trip.com car DOM extraction returned malformed rows
- Trip.com transfer cards rendered but parser did not find req
- AIbase daily selector drift: ${reason}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/ff4bb53b498ccbe5.
Report an issue: GitHub.