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

  1. 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.
  2. Inspect the current card markup and update the extraction selectors/logic to match the new '/event/<id>' link shape and title element.
  3. 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.
  4. 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

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


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/ff4bb53b498ccbe5. Report an issue: GitHub.