ReceiptsRecorded runs, model-free verdicts
VERIFIED

hhursev__recipe-scrapers-1230

VERIFIED on first verdict

1 attempt, 0 appeals. 3 files, 15 added and 2 removed lines. Tokens: 135,712 tokens. Model cost: $0.04. Sandbox time: 1 min 33 s.

The plan

Repository
hhursev/recipe-scrapers
Base commit
1414703 (image tag)
Issue
Plugins: surprising behaviour from schema.org fill plugin when implementation and metadata are both absent The `lekkerensimpel` scraper includes test coverage where some test webpages contain `schema.org` recipe metadata, and some do not. If we temporarily remove the `category` implementation -- as in the case during development of #1228 -- then we uncover a surprising change-in-behaviour: pages that do contain recipe (and category) metadata continue to return the expected result, but pages that do not now begin raising `NotImplementedError`. That's confusing: the implementation has not changed based on the HTML input, and yet the exception seems to indicate that the method is sometimes implemented, and sometimes not. The approximate cause appears to be this line of code: https://github.com/hhursev/recipe-scrapers/blob/141470384b9e8a486f3a14255d37e3b608d3383a/recipe_scrapers/plugins/schemaorg_fill.py#L60
Files to edit
  • recipe_scrapers/plugins/schemaorg_fill.py
Approach
Catch `NotImplementedError` raised by `_fix_nonexistent_value` and translate it to `RecipeSchemaNotFound` for consistency and clearer semantics.

Attempt 1

VERIFIED

Agent branch

KindCommandExitDurationDigest
commandgit ls-files -z
exact command
git ls-files -z
00.004sccce4490
writewrite recipe_scrapers/_exceptions.py
exact command
/opt/receipts-f1cb91f83e9a4d69b22b0af8a7cd4bf3/bin/busybox sh -c 'mkdir -p /recipe-scrapers/recipe_scrapers && cp /opt/receipts-f1cb91f83e9a4d69b22b0af8a7cd4bf3/incoming/66327e8876318a814ec4842d5534ea6035ed30307f5f98f23f7fd8392d01443e /recipe-scrapers/recipe_scrapers/_exceptions.py'
00.004s758eeede
commandgrep -n "NoSchemaFoundInWildMode" recipe_scrapers/__init__.py
exact command
grep -n "NoSchemaFoundInWildMode" recipe_scrapers/__init__.py
00.003sc50b3c9b
writewrite recipe_scrapers/__init__.py
exact command
/opt/receipts-91549d7c35ce4f3d840ee688b9f82591/bin/busybox sh -c 'mkdir -p /recipe-scrapers/recipe_scrapers && cp /opt/receipts-91549d7c35ce4f3d840ee688b9f82591/incoming/70ce12f659b1a2d53abc97fabd87ae34bbcde98a23ee0b8aa622f9da88b2203d /recipe-scrapers/recipe_scrapers/__init__.py'
00.005sc553fdf5
writewrite recipe_scrapers/__init__.py
exact command
/opt/receipts-baefa686450a46bbac12c6c3fb9946e7/bin/busybox sh -c 'mkdir -p /recipe-scrapers/recipe_scrapers && cp /opt/receipts-baefa686450a46bbac12c6c3fb9946e7/incoming/4129b67448224e4b063c082d08dafca53448d8f89c978ca59742d07b3d38c31c /recipe-scrapers/recipe_scrapers/__init__.py'
00.005s5dbc2df0
writewrite recipe_scrapers/plugins/schemaorg_fill.py
exact command
/opt/receipts-d1f7da9ec3e24acc839126f95fe61029/bin/busybox sh -c 'mkdir -p /recipe-scrapers/recipe_scrapers/plugins && cp /opt/receipts-d1f7da9ec3e24acc839126f95fe61029/incoming/79b9bb19529f490e243f77aab2b3bf6568aa0e872cd509a309ac877e0861a6fa /recipe-scrapers/recipe_scrapers/plugins/schemaorg_fill.py'
00.005s781a022b
writewrite recipe_scrapers/plugins/schemaorg_fill.py
exact command
/opt/receipts-6bfecd91914a49179034a7199da5d8b4/bin/busybox sh -c 'mkdir -p /recipe-scrapers/recipe_scrapers/plugins && cp /opt/receipts-6bfecd91914a49179034a7199da5d8b4/incoming/5e7aadb4531c2578cf5ec71f4f34b075f47207d5e2674932daf9e2ffc66d7bfe /recipe-scrapers/recipe_scrapers/plugins/schemaorg_fill.py'
00.005s74128429
commandpytest tests/library/test_exceptions.py::TestExceptions::test_no_schema_found_for_fill_plugin -v
exact command
/opt/receipts-73633e84c0684965b269165ac778d2c1/bin/busybox mkdir -p /opt/receipts/reports && python -I /opt/receipts-73633e84c0684965b269165ac778d2c1/receipts_pytest.py tests/library/test_exceptions.py::TestExceptions::test_no_schema_found_for_fill_plugin -v -o junit_family=xunit1 -p no:cacheprovider -rA --continue-on-collection-errors --junitxml=/opt/receipts/reports/agent1-8.xml
01.074sa1824ac42d29
commandpytest tests/library/test_exceptions.py::TestExceptions::test_no_schema_found_in_wild_mode_error -v
exact command
/opt/receipts-c067df69ff184ff6b72aeb0467a84277/bin/busybox mkdir -p /opt/receipts/reports && python -I /opt/receipts-c067df69ff184ff6b72aeb0467a84277/receipts_pytest.py tests/library/test_exceptions.py::TestExceptions::test_no_schema_found_in_wild_mode_error -v -o junit_family=xunit1 -p no:cacheprovider -rA --continue-on-collection-errors --junitxml=/opt/receipts/reports/agent1-9.xml
01.073sa1824ac42d29
commandpytest tests/library/test_exceptions.py::TestExceptions::test_website_not_implemented_error -v
exact command
/opt/receipts-90753ad74d2c451db6122ab1f8fa9ea3/bin/busybox mkdir -p /opt/receipts/reports && python -I /opt/receipts-90753ad74d2c451db6122ab1f8fa9ea3/receipts_pytest.py tests/library/test_exceptions.py::TestExceptions::test_website_not_implemented_error -v -o junit_family=xunit1 -p no:cacheprovider -rA --continue-on-collection-errors --junitxml=/opt/receipts/reports/agent1-10.xml
01.073sa1824ac42d29
commandpytest tests/library/test_exceptions.py
exact command
/opt/receipts-eb8d0ed37ebe415abead43ccaf51c1df/bin/busybox mkdir -p /opt/receipts/reports && python -I /opt/receipts-eb8d0ed37ebe415abead43ccaf51c1df/receipts_pytest.py tests/library/test_exceptions.py --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning -o junit_family=xunit1 -p no:cacheprovider -rA --continue-on-collection-errors --junitxml=/opt/receipts/reports/agent1-11.xml
01.110sa1824ac42d29
diffcapture patch
exact command
compute patch in executor staging agent1-3b83d23c5b1b4a4b8ad411a2e9f271e2: /opt/homebrew/Cellar/git/2.53.0/bin/git -c core.hooksPath=/dev/null -c core.attributesFile=/dev/null -c diff.external= -c core.quotePath=false add -A && /opt/homebrew/Cellar/git/2.53.0/bin/git -c core.hooksPath=/dev/null -c core.attributesFile=/dev/null -c diff.external= -c core.quotePath=false diff --cached --binary --no-ext-diff --no-textconv --no-renames 3c0a469173422d89fb4339d7a2544c0b490d8ba0
00.469sa1824ac42d29
Finish summary
Added RecipeSchemaNotFound exception and modified schemaorg_fill plugin to raise it when no schema.org data is present, preventing misleading NotImplementedError.
Worker outcome
finished
  • Target tests pass: yes
  • Full suite passes: yes
  • Files changed: recipe_scrapers/_exceptions.py, recipe_scrapers/__init__.py, recipe_scrapers/plugins/schemaorg_fill.py
  • Ran tests: yes

Witness branch w1

KindCommandExitDurationDigest
applyapply patch efd0f1b8a9bf
exact command
git update-index -q --refresh; git apply -v --3way --recount --ignore-space-change --whitespace=nowarn /opt/receipts-8851168451974f27b90d1c7121114317/incoming/efd0f1b8a9bf41d1fa733098e1c559a7f16272ac16dfeb9a2d18b8164af0b3b5.diff
00.020sa1824ac42d29
verificationpytest (witness) tests/library/test_exceptions.py
exact command
/opt/receipts-3bd6ea87660b4971968a4790098ae22a/bin/busybox mkdir -p /opt/receipts/reports && python -I /opt/receipts-3bd6ea87660b4971968a4790098ae22a/receipts_pytest.py --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning tests/library/test_exceptions.py -o junit_family=xunit1 -p no:cacheprovider -rA --continue-on-collection-errors --junitxml=/opt/receipts/reports/w1-2.xml
01.113sa1824ac42d29

Gate predicate checklist

PredicateNameStatusEvidence
R1_fail_to_passFailing specification tests now passPASStarget tests passed: tests/library/test_exceptions.py::TestExceptions::test_no_schema_found_for_fill_plugin, tests/library/test_exceptions.py::TestExceptions::test_no_schema_found_in_wild_mode_error, tests/library/test_exceptions.py::TestExceptions::test_website_not_implemented_error
R2_pass_to_passPreviously passing tests keptPASS0 baseline-passing tests still pass
R3_no_shrinkNo removed tests or new skipsPASSall 0 baseline tests collected; skips unchanged (0)
R4_patch_scopePatch scopePASSpatch touches 3 file(s), all in scope
R5_provenanceWitness chain and patch digestPASSagent chain 4ff01f5a -> 05020f2d unbroken over 12 receipt(s); witness chain 4ff01f5a -> 149680b8 unbroken over 2 receipt(s); applied digest matches
R6_claim_auditAgent claim audit (advisory)PASSclaimed green; own last run: 3 passed, 0 failed

What it said

Finish summary
Added RecipeSchemaNotFound exception and modified schemaorg_fill plugin to raise it when no schema.org data is present, preventing misleading NotImplementedError.
Worker outcome
finished
  • Target tests pass: yes
  • Full suite passes: yes
  • Files changed: recipe_scrapers/_exceptions.py, recipe_scrapers/__init__.py, recipe_scrapers/plugins/schemaorg_fill.py
  • Ran tests: yes

What the record shows

honest: claimed green; own last run: 3 passed, 0 failed

SWE-rebench's official grader: resolved

Agrees with the gate

Shipped patch

diff --git a/recipe_scrapers/__init__.py b/recipe_scrapers/__init__.pyindex 361c378a..9b67ce5d 100644--- a/recipe_scrapers/__init__.py+++ b/recipe_scrapers/__init__.py@@ -5,6 +5,7 @@ __all__ = (     "ElementNotFoundInHtml",     "FieldNotProvidedByWebsiteException",     "NoSchemaFoundInWildMode",+    "RecipeSchemaNotFound",     "StaticValueException",     "WebsiteNotImplementedError",     "scrape_html",@@ -26,6 +27,7 @@ from ._exceptions import (     ElementNotFoundInHtml,     FieldNotProvidedByWebsiteException,     NoSchemaFoundInWildMode,+    RecipeSchemaNotFound,     StaticValueException,     WebsiteNotImplementedError, )diff --git a/recipe_scrapers/_exceptions.py b/recipe_scrapers/_exceptions.pyindex 458e791e..6ee05228 100644--- a/recipe_scrapers/_exceptions.py+++ b/recipe_scrapers/_exceptions.py@@ -64,6 +64,15 @@ class StaticValueException(RecipeScrapersExceptions):         super().__init__(message)  +class RecipeSchemaNotFound(SchemaOrgException):+    """No schema.org recipe metadata found on the page."""++    def __init__(self, url):+        self.url = url+        message = f"No Recipe Schema found at {url}."+        super().__init__(message)++ class FieldNotProvidedByWebsiteException(StaticValueException):     """Error when, as far as we know, the website does not provide this info for any recipes.""" diff --git a/recipe_scrapers/plugins/schemaorg_fill.py b/recipe_scrapers/plugins/schemaorg_fill.pyindex d7e05e69..6e2b0c40 100644--- a/recipe_scrapers/plugins/schemaorg_fill.py+++ b/recipe_scrapers/plugins/schemaorg_fill.py@@ -1,7 +1,7 @@ import functools import logging -from recipe_scrapers._exceptions import FillPluginException+from recipe_scrapers._exceptions import FillPluginException, RecipeSchemaNotFound from recipe_scrapers.settings import settings  from ._interface import PluginInterface@@ -56,8 +56,10 @@ class SchemaOrgFillPlugin(PluginInterface):             try:                 return decorated(self, *args, **kwargs)             except (FillPluginException, NotImplementedError) as e:+                if not self.schema.data:+                    raise RecipeSchemaNotFound(self.url)                 function = getattr(self.schema, decorated.__name__)-                if self.schema.data and function:+                if function:                     logger.info(                         f"{class_name}.{method_name}() seems to not be implemented but .schema is available! Attempting to return result from SchemaOrg."                     )

Model and costs

Model
NVIDIA Nemotron 3 Super thinking off · temperature 1.0 · top_p 0.95
Tokens
135,712 tokens
Model cost
$0.04
Sandbox time
1 min 33 s
Sandbox cost
Token Factory reported cost: 0.111 (unit not published)
Full environment disclosure
{
  "executor_kind": "tokenfactory",
  "lock_sha256": "3a3a78d50a5a32620f014112490e95d5e1ca35135455e41ea52e4a6ab1c61fae",
  "model": {
    "base_url": "https://api.tokenfactory.nebius.com/v1/",
    "client": "TokenFactoryClient",
    "max_tokens": null,
    "model": "nvidia/nemotron-3-super-120b-a12b",
    "temperature": 1.0,
    "thinking": false,
    "top_p": 0.95
  },
  "pytest_config_digests": {
    "pyproject.toml": "f34018c4aacf68bf69a0f40477f397059c75fc503db67c490775ca5f626bc1d0",
    "tox.ini": "91ba1e5f0d384b99fd2f497db17b2baba62e7dae7118b8b3345927c553a2d884"
  },
  "receipts_version": "0.0.1",
  "test_digests": {
    "tests/library/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    "tests/library/test_exceptions.py": "30216284aa50ba0021778834c8f7feed9e3c633ccbc994abc641f3d5504900a1",
    "tests/library/test_grouping_utils.py": "e83854d6c3ff054b98fda09ef7cad85200c8e739a83ec1bc728b6d16f6499dfe",
    "tests/library/test_json_order.py": "4ba802046cb7d14b60414556db83e2cdb4f20cac3b3def9fa04c7fb6cdfd0829",
    "tests/library/test_main_methods.py": "b1b7fc6d8e8f6a58f7e90cd0837f687daeba44636d72bebcdae7831e7ddeeed9",
    "tests/library/test_nutrition_order.py": "1c9f2ca06d222b0cc352c5b5320795006b741de114ad183d2cbe92c73014c093",
    "tests/library/test_plugin_htmltagstripper.py": "3700b67169392770e4e0ba9f2632690e3d46b142ee4c4f5609dd31f031b5ef84",
    "tests/library/test_readme.py": "55a8b8783a79eef7158a6bc04ef15e36998d5b447c83e27412842bb3f6e165f8",
    "tests/library/test_utils.py": "ca923bda9ceca6e7cff8d5f49d74bcd6c7cebba3f96f3a536ceeee2d0e8c12cf"
  }
}

The bundle

Recorded JSON and patches. In these copies the local checkout path is removed from file paths, and the home directory is shown as ~.