jackwener/OpenCLI · error · Error

未找到匹配「${courseFilter}」的课程

Error message

未找到匹配「${courseFilter}」的课程

What it means

After filtering the course list by a courseFilter substring on c.title, if no course title matches, the library throws a plain Error with the filter in the message. This is a user-input mismatch, not an auth problem — the session worked and courses were fetched, but none contained the given string.

Source

Thrown at clis/chaoxing/assignments.js:36

            help: '按状态过滤',
        },
        { name: 'limit', type: 'int', default: 20, help: '最大返回数量' },
        { name: 'timeout', type: 'int', required: false, default: 90, help: 'Max seconds for the overall command (default: 90)' },
    ],
    columns: ['rank', 'course', 'title', 'deadline', 'status', 'score'],
    func: async (page, kwargs) => {
        const { course: courseFilter, status: statusFilter = 'all', limit = 20 } = kwargs;
        // 1. Establish session
        await initSession(page);
        // 2. Get courses
        const courses = await getCourses(page);
        if (!courses.length)
            throw new AuthRequiredError('mooc2-ans.chaoxing.com', '未获取到课程列表');
        const filtered = courseFilter
            ? courses.filter(c => c.title.includes(courseFilter))
            : courses;
        if (courseFilter && !filtered.length) {
            throw new Error(`未找到匹配「${courseFilter}」的课程`);
        }
        // 3. Per-course: enter → click 作业 tab → navigate to iframe → parse
        const allRows = [];
        for (const c of filtered) {
            try {
                await enterCourse(page, c);
                const iframeUrl = await getTabIframeUrl(page, '作业');
                if (!iframeUrl)
                    continue;
                await page.goto(iframeUrl);
                await page.wait(2);
                const rows = await parseAssignmentsFromDom(page, c.title);
                allRows.push(...rows);
            }
            catch {
                // Single course failure: skip, continue
            }
            if (filtered.length > 1)

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Run assignments without the course filter to list exact available titles, then copy one verbatim
  2. Check for whitespace/full-width character differences between your filter and the real title
  3. Use a shorter, unique substring of the title instead of the full name
  4. Adjust the filter to match the current semester's course name

Example fix

// before
await runAssignments({ course: '高等数学' });
// after
const courses = await listCourses(page); // inspect exact titles first
await runAssignments({ course: courses.find(c => c.title.includes('高等数学')).title.slice(0, 6) });
Defensive patterns

Strategy: validation

Validate before calling

const courses = await listCourses(page);
const match = courses.find(c => c.title.includes(courseFilter));
if (!match) throw new Error(`Available: ${courses.map(c => c.title).join(', ')}`);

Type guard

null

Try / catch

try { await assignments(page, { course: courseFilter }); }
catch (e) { if (e.message.includes('未找到匹配')) { console.error('Course not found; run without --course to list titles'); return listCourses(page); } throw e; }

Prevention

When it happens

Trigger: Running assignments with --course/课程名 substring that doesn't exactly match any course title (typos, extra spaces, abbreviated names, semester-suffixed titles).

Common situations: Typing a shortened course name when the title contains extra terms; course renamed for the new semester; full-width vs half-width characters in Chinese titles.

Related errors


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