diff --git a/changedetectionio/html_tools.py b/changedetectionio/html_tools.py
index 7eade3bc6..0d8ce03c1 100644
--- a/changedetectionio/html_tools.py
+++ b/changedetectionio/html_tools.py
@@ -630,7 +630,7 @@ def extract_json_blob_from_html(content, ensure_is_ldjson_info_type, json_filter
# result.text is how bs4 magically strips JSON from the body
content_start = result.text.lstrip("\ufeff").strip()[:100] if result.text else ''
# Skip empty tags, and things that dont even look like JSON
- if not result.text or not (content_start[0] == '{' or content_start[0] == '['):
+ if not content_start or not (content_start[0] == '{' or content_start[0] == '['):
continue
try:
json_data = json.loads(result.text)
@@ -682,7 +682,7 @@ def extract_json_as_string(content, json_filter, ensure_is_ldjson_info_type=None
content_start = content.lstrip("\ufeff").strip()[:100]
- if content_start[0] == '{' or content_start[0] == '[':
+ if content_start and (content_start[0] == '{' or content_start[0] == '['):
try:
# .lstrip("\ufeff") strings ByteOrderMark from UTF8 and still lets the UTF work
stripped_text_from_html = _parse_json(json.loads(content.lstrip("\ufeff")), json_filter)
diff --git a/changedetectionio/tests/test_jsonpath_jq_selector.py b/changedetectionio/tests/test_jsonpath_jq_selector.py
index cf035d166..eb47d147d 100644
--- a/changedetectionio/tests/test_jsonpath_jq_selector.py
+++ b/changedetectionio/tests/test_jsonpath_jq_selector.py
@@ -121,6 +121,31 @@ and it can also be repeated
html_tools.extract_json_as_string('COMPLETE GIBBERISH, NO JSON!', "jqraw:.id")
+def test_blank_content_does_not_raise_indexerror():
+ """Empty / whitespace-only content must take the normal JSONNotFound path, not crash.
+
+ The content-sniffing peeked at content_start[0] to see if the body looked like JSON.
+ A blank body left content_start empty, so that peek raised IndexError instead of
+ letting the caller report 'no JSON found' the way any other non-JSON body does.
+ See https://github.com/dgtlmoon/changedetection.io/issues/4531
+ """
+ from .. import html_tools
+
+ # Blank bodies with a json: filter set - the same as any other non-JSON content
+ for blank in ('', ' ', '\n', '\r\n\t '):
+ with pytest.raises(html_tools.JSONNotFound):
+ html_tools.extract_json_as_string(blank, "json:$.id")
+
+ # Same on the html blob path, where a whitespace-only