Resume-Matcher icon indicating copy to clipboard operation
Resume-Matcher copied to clipboard

Submitting Improve always failed with status 500, details in post

Open robertwt7 opened this issue 5 months ago • 14 comments

Describe the bug This is all happening when i'm running everything locally, after make setup and make run-dev, everything is working

However after I uploaded my resume and enter the job description. Pressing Improve always returns me with:

Improve failed with status 500: {"detail":"sorry, something went wrong!","request_id":"resumes:f356f24a-497e-4838-985f-107f6e44cfa2"}

This is the traceback:

[dev:backend] [2025-07-23T16:07:52+1000 - app.services.job_service - INFO] Job ID: 17494bcc-9482-422c-a453-9d73e7566d20
[dev:backend] [2025-07-23T16:08:48+1000 - app.api.router.v1.resume - ERROR] Error: 'NoneType' object has no attribute 'extracted_keywords' - traceback: Traceback (most recent call last):
[dev:backend]   File "/Users/r/Development/Resume-Matcher/apps/backend/app/api/router/v1/resume.py", line 137, in score_and_improve
[dev:backend]     improvements = await score_improvement_service.run(
[dev:backend]                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[dev:backend]   File "/Users/r/Development/Resume-Matcher/apps/backend/app/services/score_improvement_service.py", line 173, in run
[dev:backend]     json.loads(processed_resume.extracted_keywords).get(
[dev:backend]                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[dev:backend] AttributeError: 'NoneType' object has no attribute 'extracted_keywords'

I've also tried this with multiple different resume as well. does this mean that the resume is not AST friendly or something?

robertwt7 avatar Jul 23 '25 06:07 robertwt7

Exactly the same issue with my PDF resume. Maybe this is what's happening on the backend of the ATS for all the jobs I've applied to as well! LOL.

scottvr avatar Jul 23 '25 06:07 scottvr

lolol, ~~mine is docx file but that's what I thought too~~ mine is also pdf. I thought my resume never passed the ATS screening!! @scottvr

robertwt7 avatar Jul 23 '25 12:07 robertwt7

@robertwt7 and @scottvr you're using resume.docx??

srbhr avatar Jul 23 '25 13:07 srbhr

Failing for me too.

irshad437 avatar Jul 23 '25 14:07 irshad437

@robertwt7 and @scottvr you're using resume.docx??

No. Mine is a 69kB PDF file.

Incidentally, I tried copilot's fix-421 branch and now although I can see the text from my resume being sent to the backend and the ollama runner starting, 30 minutes later and no response from the backend. The box is CUDA and I can chat with llama3.2 in realtime, so I don't think there is an ollama issue that suddenly appeared. Just thought you might like to know; i tried to test the fix, but for some reason I can't even get to the job description page today, while the original trouble occurred after uploading the resume and being given the button to enter a job description.

scottvr avatar Jul 23 '25 16:07 scottvr

actually mine is also pdf i don't know why i thought its docx :/ @srbhr , i already exported it as pdf

i haven't got a chance to look at the code or debug but i saw that backend has logged extracted_keywords so it shouldn't be None when trying to access it here processed_resume.extracted_keywords

robertwt7 avatar Jul 23 '25 22:07 robertwt7

same error message, also tried using a very simplified text version of my resume, keywords extraction looks good. installed locally linux; npm start.

After submtting any number of Job Description, clicking on "Improve" button leads to msg: Improve failed with status 500: {"detail":"sorry, something went wrong!","request_id":"resumes:4ef76463-f54f-4622-bd21-733a090b31ed"}

davidchilin avatar Jul 24 '25 01:07 davidchilin

Also getting same error Improve failed with status 500: {"detail":"sorry, something went wrong!","request_id":"resumes:81cf981a-289a-49cb-a548-28b89d2e5149"} --- Anyone know any fixes to this?

abmilo avatar Jul 24 '25 13:07 abmilo

@davidchilin @abmilo your errors don't show a lot of information. If you post the output of your PowerShell window, people are able to help you. Now it's just: "error: [random number]"

I'm getting a similar error, this is the output in my PowerShell:

[dev:backend] [2025-07-24T19:11:14+0200 - app.agent.strategies.wrapper - INFO] Saving JSON to: C:\dev\Resume-Matcher\apps\backend\raw_provider_response.json
[dev:backend] [2025-07-24T19:11:14+0200 - app.services.job_service - INFO] Job ID: (my jobID)
[dev:backend] [2025-07-24T19:11:45+0200 - app.api.router.v1.resume - ERROR] Parsing of resume with ID (my resumeID) failed.

Digging some more:

apps\backend\app\api\router\v1\resume.py shows that the error messages are loaded from app.services. In apps\backend\app\services\exceptions.py, this specific piece of code is relevant:

class ResumeParsingError(Exception):
    """
    Exception raised when a resume processing and storing in the database failed.
    """

    def __init__(self, resume_id: Optional[str] = None, message: Optional[str] = None):
        if resume_id and not message:
            message = f"Parsing of resume with ID {resume_id} failed."
        elif not message:
            message = "Parsed resume not found."
        super().__init__(message)
        self.resume_id = resume_id

I'm not sure, but it seems like the body of the message is empty (the parsed JSON is not, I have added a step that saves the json file)

Digging a bit further, I see the following function being called in score_improvement_service.py that throws the error:

    async def _get_resume(
        self, resume_id: str
    ) -> Tuple[Resume | None, ProcessedResume | None]:
        """
        Fetches the resume from the database.
        """
        query = select(Resume).where(Resume.resume_id == resume_id)
        result = await self.db.execute(query)
        resume = result.scalars().first()

        if not resume:
            raise ResumeNotFoundError(resume_id=resume_id)

        query = select(ProcessedResume).where(ProcessedResume.resume_id == resume_id)
        result = await self.db.execute(query)
        processed_resume = result.scalars().first()

        if not processed_resume:
            raise ResumeParsingError(resume_id=resume_id)

It seems like there is no processed resume present.

In the same file (score_improvement_service.py), this is the piece of code that is causing the error, I think:

    async def run(self, resume_id: str, job_id: str) -> Dict:
        """
        Main method to run the scoring and improving process and return dict.
        """
        resume, processed_resume = await self._get_resume(resume_id)
        job, processed_job = await self._get_job(job_id)

        extracted_job_keywords = ", ".join(
            json.loads(processed_job.extracted_keywords).get("extracted_keywords", [])
        )

        extracted_resume_keywords = ", ".join(
            json.loads(processed_resume.extracted_keywords).get(
                "extracted_keywords", []
            )
        )

        resume_embedding_task = asyncio.create_task(
            self.embedding_manager.embed(resume.content)
        )
        job_kw_embedding_task = asyncio.create_task(
            self.embedding_manager.embed(extracted_job_keywords)
        )
        resume_embedding, extracted_job_keywords_embedding = await asyncio.gather(
            resume_embedding_task, job_kw_embedding_task
        )

        cosine_similarity_score = self.calculate_cosine_similarity(
            extracted_job_keywords_embedding, resume_embedding
        )
        updated_resume, updated_score = await self.improve_score_with_llm(
            resume=resume.content,
            extracted_resume_keywords=extracted_resume_keywords,
            job=job.content,
            extracted_job_keywords=extracted_job_keywords,
            previous_cosine_similarity_score=cosine_similarity_score,
            extracted_job_keywords_embedding=extracted_job_keywords_embedding,
        )

        resume_preview = await self.get_resume_for_previewer(
            updated_resume=updated_resume
        )

        logger.info(f"Resume Preview: {resume_preview}")

        execution = {
            "resume_id": resume_id,
            "job_id": job_id,
            "original_score": cosine_similarity_score,
            "new_score": updated_score,
            "updated_resume": markdown.markdown(text=updated_resume),
            "resume_preview": resume_preview,
        }

        gc.collect()

        return execution

Specifially: resume, processed_resume = await self._get_resume(resume_id)

The processed_resume is taken from apps\backend\app\models\resume.py. The class ProcessedResume includes the following:

personal_data = Column(JSON, nullable=False)
experiences = Column(JSON, nullable=True)
projects = Column(JSON, nullable=True)
skills = Column(JSON, nullable=True)
research_work = Column(JSON, nullable=True)
achievements = Column(JSON, nullable=True)
education = Column(JSON, nullable=True)
extracted_keywords = Column(JSON, nullable=True)

This is the JSON that is created:


{
  "UUID": "a1b2c3d4-5678-9012-3456-789012345678",
  "Personal Data": {
    "firstName": "(my first name)",
    "lastName": "(my last name)",
    "email": "(email)@gmail.,",
    "phone": null,
    "linkedin": null,
    "portfolio": "https://www.example.com",
    "location": {
      "city": "(my city)",
      "country": "(my country)"
      }
  },

Seeing as personal_data is not nullable, I think this is part of the core of the issue.

Moosdijk avatar Jul 24 '25 16:07 Moosdijk

I think this is the same bug as #445, or at least the same symptoms.

elliotclee avatar Jul 24 '25 22:07 elliotclee

Kinda having the same issue. 😥

Image
[dev:backend] [2025-07-25T17:28:10+0200 - app.services.job_service - INFO] Validation error: 1 validation error for StructuredJobModel
[dev:backend] employmentType
[dev:backend]   Input should be 'Full-time', 'Part-time', 'Contract', 'Internship', 'Temporary' or 'Not Specified' [type=enum, input_value='Permanent', input_type=str]
[dev:backend]     For further information visit https://errors.pydantic.dev/2.11/v/enum
[dev:backend] [2025-07-25T17:28:10+0200 - app.services.job_service - INFO] Structured job extraction failed.
[dev:backend] [2025-07-25T17:28:10+0200 - app.services.job_service - INFO] Job ID: c43af2b1-9dad-4230-a856-dfd245d26651
[dev:backend] [2025-07-25T17:28:14+0200 - app.api.router.v1.resume - ERROR] Parsing of job with ID c43af2b1-9dad-4230-a856-dfd245d26651 failed.

PoshoDev avatar Jul 25 '25 15:07 PoshoDev

You already have a clue what goes wrong: Your job description probably lists a position type "permanent" while that is not one of the keywords that RM looks for. What happens if you change it to "Full-time"?

Moosdijk avatar Jul 25 '25 15:07 Moosdijk

What happens if you change it to "Full-time"?

That actually did help, it finished the job without any errors now. Thank you!

PoshoDev avatar Jul 25 '25 16:07 PoshoDev

You already have a clue what goes wrong: Your job description probably lists a position type "permanent" while that is not one of the keywords that RM looks for. What happens if you change it to "Full-time"?

Thanks a lot, and it worked for me as well

akorez avatar Sep 24 '25 20:09 akorez