Skip to content

[BUG] RobotCode analyze CLI has regression when file import paths contain variables #632

Description

@MikeAckerschott

Describe the bug

Within the codebase i work on, there are alot of imports happening that contain variables in which we can easily switch from configuration

For example:

Variables           Resources/Generated/${CONFIGURATION_NAME}/varfile1.py
Variables           Resources/Generated/${CONFIGURATION_NAME}/varfile2.py
Variables           Resources/Generated/${CONFIGURATION_NAME}/varfile3.py
Resource           Resources/Generated/${CONFIGURATION_NAME}/some_resource.resource

the codebase im working on has 390 robotcode analysable files and 133 of those files do variable or resource imports using the CONFIGURATION_NAME variable 1 or multiple times. I have noticed that RobotCode's analyze code function is quite slow in our codebase compared to those of others. analysing the whole project takes 38 minutes. After some investigation, i have noticed that replacing all occurences of /${CONFIGURATION_NAME}/ to their dedicated value (for example "config1" ) would reduce the analyse time from 38 minutes to 4 minutes, making me believe that there still is some regression regarding variable lookup in either robotcode or robotframework itself.

I obviously cant share the codebase, but i am able to share cProfile statistics and if desired can create a similar import structure to reproducce this issue.

The 38 minute analysation shows this:

(venv) PS C:\Development> python -m pstats .\robotcode.prof                                                                     
Welcome to the profile statistics browser.
.\robotcode.prof% sort cumtime
.\robotcode.prof% stats 50
Wed Jul  8 08:53:08 2026    .\robotcode.prof

         5105875728 function calls (5051842651 primitive calls) in 2292.713 seconds

   Ordered by: cumulative time
   List reduced from 7197 to 50 due to restriction <50>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   1506/1    0.122    0.000 2294.995 2294.995 {built-in method builtins.exec}
        1    0.001    0.001 2294.995 2294.995 .\test\AutomatedRobotTests\Tools\robotcode_cli_fixed.py:1(<module>)
        1    0.000    0.000 2293.568 2293.568 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\click\core.py:1567(__call__)
        1    0.000    0.000 2293.568 2293.568 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\click\core.py:1422(main)
      2/1    0.000    0.000 2293.565 2293.565 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\click\core.py:1936(invoke)
        3    0.000    0.000 2293.561  764.520 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\click\core.py:1339(invoke)
      6/3    0.000    0.000 2293.561  764.520 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\click\core.py:853(invoke)
        3    0.000    0.000 2293.561  764.520 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\click\decorators.py:77(new_func)
        1    0.002    0.002 2293.561 2293.561 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\analyze\code\cli.py:269(code)
      392    0.003    0.000 2291.487    5.846 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\analyze\code\code_analyzer.py:87(run)
1563/1171    0.006    0.000 2289.392    1.955 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\core\event.py:106(__call__)
3516/3122    0.009    0.000 2289.387    0.733 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\core\event.py:73(_notify)
     4749    0.016    0.000 2289.062    0.482 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\core\text_document.py:337(get_cache)
     1560    0.003    0.000 2289.037    1.467 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\document_cache_helper.py:373(get_namespace)
      390    0.003    0.000 2289.037    5.869 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\analyze\code\diagnostics_context.py:29(analyze_document)
      390    0.001    0.000 2289.020    5.869 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\analyze\code\robot_framework_language_provider.py:116(analyze_document)
      390    0.086    0.000 2288.965    5.869 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\document_cache_helper.py:434(__get_namespace_for_document_type)
      390    0.003    0.000 2268.304    5.816 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\import_resolver.py:119(resolve)
43914/390    0.406    0.000 2268.232    5.816 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\import_resolver.py:219(_handle_imports)
261940/2052    0.435    0.000 2268.211    1.105 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\import_resolver.py:244(_dispatch_import)
187659/1673    1.463    0.000 2257.599    1.349 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\import_resolver.py:391(_import_resource)
    22985   23.793    0.001 2212.525    0.096 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\library_doc.py:1886(resolve_robot_variables)
   251246    1.058    0.000 2107.695    0.008 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\core\utils\caching.py:39(get)
    29494    0.486    0.000 1932.680    0.066 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\import_resolver.py:535(_import_variables)
    29494    0.504    0.000 1931.388    0.065 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\imports_manager.py:1835(get_libdoc_for_variables_import)
    29537    0.096    0.000 1930.127    0.065 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\imports_manager.py:1512(find_variables)
    19435    0.081    0.000 1924.941    0.099 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\imports_manager.py:1530(__find_variables)
    19435    0.037    0.000 1924.773    0.099 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\library_doc.py:2560(find_variables)
    19435    1.497    0.000 1924.736    0.099 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\library_doc.py:2511(_find_variables_internal)
      258    0.017    0.000 1619.884    6.279 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\namespace.py:740(build)
      258    0.003    0.000 1606.774    6.228 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\namespace_analyzer.py:163(resolve)
      980    0.001    0.000 1542.110    1.574 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\document_cache_helper.py:383(get_resource_namespace)
      245    0.010    0.000 1542.099    6.294 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\document_cache_helper.py:386(__get_resource_namespace)
    22984    0.041    0.000 1323.077    0.058 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\variables.py:51(resolve_delayed)
    22984   17.884    0.001 1323.036    0.058 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\store.py:32(resolve_delayed)
35013451/29515642   23.173    0.000 1210.986    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\store.py:42(_resolve_delayed)
14157372/13883921   17.616    0.000 1088.659    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\tablesetter.py:95(resolve)
117700400/74018318   81.276    0.000  913.687    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\replacer.py:96(_replace)
21478414/20927455   21.767    0.000  753.983    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\replacer.py:113(_get_variable_value)
      536    0.000    0.000  745.413    1.391 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\document_cache_helper.py:395(get_general_namespace)
      134    0.011    0.000  745.407    5.563 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\document_cache_helper.py:398(__get_general_namespace)
 50389792   71.924    0.000  736.079    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\store.py:97(_undecorate)
      390    0.016    0.000  663.908    1.702 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\document_cache_helper.py:494(_try_load_cached_namespace)
      132    0.235    0.002  661.974    5.015 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\namespace.py:542(from_data)
 28733026   22.336    0.000  624.362    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\store.py:87(add)
21656766/21218799   31.340    0.000  585.197    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\finders.py:43(find)
    22984    0.055    0.000  544.613    0.024 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\variables.py:71(set_from_variable_section)
    22984    8.394    0.000  544.554    0.024 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\tablesetter.py:35(set)
206301045  124.484    0.000  533.724    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\search.py:23(search_variable)
71868206/71147908   46.083    0.000  504.582    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\search.py:114(resolve_base)


.\robotcode.prof% 

And the 'optimized' analysation (in which i replaced all occurences of /${CONFIGURATION_NAME}/ to their dedicated value (for example "config1" ) shows this:

(venv) PS C:\Development> python -m pstats .\robotcode_optimized.prof
Welcome to the profile statistics browser.
.\robotcode_optimized.prof% sort cumtime
.\robotcode_optimized.prof% stats 50
Wed Jul  8 09:18:06 2026    .\robotcode_optimized.prof

         613428866 function calls (607431135 primitive calls) in 255.676 seconds

   Ordered by: cumulative time
   List reduced from 7212 to 50 due to restriction <50>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   1506/1    0.125    0.000  256.496  256.496 {built-in method builtins.exec}
        1    0.001    0.001  256.496  256.496 .\test\AutomatedRobotTests\Tools\robotcode_cli_fixed.py:1(<module>)
        1    0.000    0.000  255.277  255.277 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\click\core.py:1567(__call__)
        1    0.000    0.000  255.277  255.277 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\click\core.py:1422(main)
      2/1    0.000    0.000  255.274  255.274 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\click\core.py:1936(invoke)
        3    0.000    0.000  255.272   85.091 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\click\core.py:1339(invoke)
      6/3    0.000    0.000  255.272   85.091 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\click\core.py:853(invoke)
        3    0.000    0.000  255.272   85.091 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\click\decorators.py:77(new_func)
        1    0.002    0.002  255.272  255.272 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\analyze\code\cli.py:269(code)
      392    0.003    0.000  253.172    0.646 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\analyze\code\code_analyzer.py:87(run)
1563/1171    0.006    0.000  251.108    0.214 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\core\event.py:106(__call__)
3516/3122    0.009    0.000  251.103    0.080 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\core\event.py:73(_notify)
     4749    0.016    0.000  250.841    0.053 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\core\text_document.py:337(get_cache)
     1560    0.003    0.000  250.817    0.161 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\document_cache_helper.py:373(get_namespace)
      390    0.003    0.000  250.814    0.643 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\analyze\code\diagnostics_context.py:29(analyze_document)
      390    0.001    0.000  250.798    0.643 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\analyze\code\robot_framework_language_provider.py:116(analyze_document)
      390    0.093    0.000  250.741    0.643 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\document_cache_helper.py:434(__get_namespace_for_document_type)
      385    0.021    0.000  244.434    0.635 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\namespace.py:740(build)
      385    0.004    0.000  226.093    0.587 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\namespace_analyzer.py:163(resolve)
      390    0.003    0.000  226.069    0.580 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\import_resolver.py:119(resolve)
43945/390    0.293    0.000  226.002    0.579 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\import_resolver.py:219(_handle_imports)
262361/2350    0.331    0.000  225.981    0.096 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\import_resolver.py:244(_dispatch_import)
187995/1944    1.109    0.000  224.308    0.115 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\import_resolver.py:391(_import_resource)
     2365    3.486    0.001  188.267    0.080 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\library_doc.py:1886(resolve_robot_variables)
      980    0.001    0.000  160.549    0.164 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\document_cache_helper.py:383(get_resource_namespace)
      245    0.017    0.000  160.538    0.655 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\document_cache_helper.py:386(__get_resource_namespace)
    44821    0.512    0.000  119.382    0.003 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\import_resolver.py:312(_import_library)
    45601    0.423    0.000  117.649    0.003 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\imports_manager.py:1667(get_libdoc_for_library_import)
    45600    0.105    0.000  111.745    0.002 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\library_doc.py:2535(resolve_args)
     2365    0.005    0.000  110.871    0.047 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\variables.py:51(resolve_delayed)
     2365    1.520    0.001  110.866    0.047 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\store.py:32(resolve_delayed)
3257643/2760976    1.950    0.000  101.289    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\store.py:42(_resolve_delayed)
1340887/1316354    1.507    0.000   90.775    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\tablesetter.py:95(resolve)
      536    0.000    0.000   89.487    0.167 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\document_cache_helper.py:395(get_general_namespace)
      134    0.010    0.000   89.482    0.668 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\document_cache_helper.py:398(__get_general_namespace)
   263210    0.599    0.000   79.734    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\core\utils\caching.py:39(get)
10878450/6861767    6.824    0.000   77.181    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\replacer.py:96(_replace)
1974847/1921388    1.810    0.000   62.975    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\replacer.py:113(_get_variable_value)
  4672124    6.084    0.000   62.760    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\store.py:97(_undecorate)
    29545    0.221    0.000   61.719    0.002 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\import_resolver.py:535(_import_variables)
    29545    0.199    0.000   61.035    0.002 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\imports_manager.py:1835(get_libdoc_for_variables_import)
    29553    0.039    0.000   60.469    0.002 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\imports_manager.py:1512(find_variables)
      598    0.003    0.000   60.030    0.100 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\imports_manager.py:1530(__find_variables)
      598    0.002    0.000   60.025    0.100 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\library_doc.py:2560(find_variables)
      598    0.047    0.000   60.023    0.100 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robotcode\robot\diagnostics\library_doc.py:2511(_find_variables_internal)
  2679354    1.896    0.000   53.867    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\store.py:87(add)
 20601285   11.310    0.000   49.249    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\search.py:23(search_variable)
1992770/1951436    2.491    0.000   48.801    0.000 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\finders.py:43(find)
     2365    0.006    0.000   46.936    0.020 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\variables.py:71(set_from_variable_section)
     2365    0.740    0.000   46.929    0.020 C:\Development\test\AutomatedRobotTests\venv\Lib\site-packages\robot\variables\tablesetter.py:35(set)

most notable is the difference in the amount of calls to library_doc.py:1886(resolve_robot_variables). this call takes between 0.080 and 0.096 seconds but is called 22985 in the normal analysation and only 2365 in the optimized situation, which would explain the difference in runtime

Steps To Reproduce
not exactly clear, i can try to create a project/file structure in which the difference is clear

Expected behavior
During static code analysis the value of variables shouldn't change (unless there is some robotframework specific stuff im missing). I'd expect the variable value lookup of variables in import names to happen once and the value to be remembered during the run, so that rerunning the variable lookup for every import is not needed (unless it is possible to have the same variable name with different values in multiple resource files)

Screenshots/ Videos
N.A.

Logs
N.A.

Additional context
Im not super familiar with the innerworkings of either robotframework or robotcode, so whether my expected behavior is reasonable, i dont know. I do know that the codebase im working in is far from optimal regarding the import structure, but the runtime difference is still surprising. We also use other variables than CONFIGURATION_NAME in file imports, but CONFIGURATION_NAME is by far the most used variable in this case

AI / tooling disclosure
N.A.

Desktop (please complete the following information):

  • RobotCode Version [2.6.2]
  • OS: [Windows 11]
  • Python Version [3.14.5]
  • RobotFramework Version [7.3.2]
  • Additional tools like robocop [8.3.2]

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions