{"id":"81e002a4b500b8e8","repo":"pypa/pip","slug":"unexpected-trailing-data-s","errorCode":null,"errorMessage":"unexpected trailing data: %s","messagePattern":"unexpected trailing data: (.+?)","errorType":"validation","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"src/pip/_vendor/distlib/util.py","lineNumber":259,"sourceCode":"                else:\n                    m = VERSION_IDENTIFIER.match(s)\n                    if not m:\n                        raise SyntaxError('invalid constraint: %s' % s)\n                    v = m.groups()[0]\n                    s = s[m.end():].lstrip()\n                    if s:\n                        raise SyntaxError('invalid constraint: %s' % s)\n                    versions = [('~=', v)]\n\n    if remaining:\n        if remaining[0] != ';':\n            raise SyntaxError('invalid requirement: %s' % remaining)\n        remaining = remaining[1:].lstrip()\n\n        mark_expr, remaining = parse_marker(remaining)\n\n    if remaining and remaining[0] != '#':\n        raise SyntaxError('unexpected trailing data: %s' % remaining)\n\n    if not versions:\n        rs = distname\n    else:\n        rs = '%s %s' % (distname, ', '.join(['%s %s' % con for con in versions]))\n    return Container(name=distname, extras=extras, constraints=versions, marker=mark_expr, url=uri, requirement=rs)\n\n\ndef get_resources_dests(resources_root, rules):\n    \"\"\"Find destinations for resources files\"\"\"\n\n    def get_rel_path(root, path):\n        # normalizes and returns a lstripped-/-separated path\n        root = root.replace(os.path.sep, '/')\n        path = path.replace(os.path.sep, '/')\n        assert path.startswith(root)\n        return path[len(root):].lstrip('/')\n","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_vendor/distlib/util.py#L241-L277","documentation":"Raised by parse_requirement() at the very end of parsing: after the name, versions, URL, and any environment marker have been consumed, if non-empty text remains whose first character is not '#' (comment), a SyntaxError 'unexpected trailing data' is raised. It is the final integrity check that the whole requirement string was consumed.","triggerScenarios":"parse_requirement('pkg >= 1.0 ; python_version >= \"3.8\" extra'), parse_requirement('pkg ; python_version >= \"3\" )'), or any requirement where characters survive after the marker expression is parsed.","commonSituations":"Malformed marker expressions that terminate early (e.g. unbalanced quotes/parens inside the marker), or stray characters appended after a valid requirement.","solutions":["Examine the trailing data reported and remove it.","If the trailing data is part of a marker, fix the marker syntax (balance quotes and parentheses) so the whole marker is consumed.","Split compound lines into one requirement per line."],"exampleFix":"// before\nparse_requirement('pkg >= 1.0 ; python_version >= \"3.8\")')\n// after\nparse_requirement('pkg >= 1.0 ; python_version >= \"3.8\"')","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"from distlib.util import parse_requirement\ntry:\n    spec = parse_requirement(raw)\nexcept SyntaxError as e:\n    if 'unexpected trailing data' in str(e):\n        log_trailing(raw, e)\n    else:\n        raise","preventionTips":["Ensure marker expressions are syntactically complete (balanced quotes/parens).","Avoid appending extra tokens after a valid requirement.","Test every requirement string through parse_requirement() during build validation."],"tags":["requirement","parsing","pep508","packaging","validation"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}